@qite/tide-booking-component 1.3.4 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/build-cjs/booking-wizard/features/sidebar/sidebar-util.d.ts +3 -3
- package/build/build-cjs/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +5 -5
- package/build/build-cjs/booking-wizard/types.d.ts +6 -0
- package/build/build-cjs/index.js +223 -147
- package/build/build-cjs/shared/utils/localization-util.d.ts +2 -0
- package/build/build-esm/booking-wizard/features/sidebar/sidebar-util.d.ts +3 -3
- package/build/build-esm/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +5 -5
- package/build/build-esm/booking-wizard/types.d.ts +6 -0
- package/build/build-esm/index.js +223 -147
- package/build/build-esm/shared/utils/localization-util.d.ts +2 -0
- package/package.json +75 -75
- package/src/booking-wizard/components/print-offer-button.tsx +63 -63
- package/src/booking-wizard/features/booking/booking-self-contained.tsx +389 -389
- package/src/booking-wizard/features/booking/booking-slice.ts +663 -663
- package/src/booking-wizard/features/booking/booking.tsx +361 -361
- package/src/booking-wizard/features/flight-options/flight-utils.ts +522 -522
- package/src/booking-wizard/features/product-options/options-form.tsx +481 -481
- package/src/booking-wizard/features/sidebar/sidebar-util.ts +177 -177
- package/src/booking-wizard/features/summary/summary-booking-option-pax.tsx +25 -25
- package/src/booking-wizard/features/summary/summary.tsx +674 -674
- package/src/booking-wizard/features/travelers-form/travelers-form-slice.ts +164 -164
- package/src/booking-wizard/features/travelers-form/travelers-form.tsx +888 -754
- package/src/booking-wizard/settings-context.ts +62 -62
- package/src/booking-wizard/types.ts +286 -279
- package/src/booking-wizard/use-offer-printer.ts +117 -117
- package/src/shared/translations/en-GB.json +239 -237
- package/src/shared/translations/fr-BE.json +239 -238
- package/src/shared/translations/nl-BE.json +239 -237
- package/src/shared/utils/tide-api-utils.ts +36 -36
- package/styles/booking-wizard-variables.scss +873 -873
- package/styles/components/_booking.scss +879 -879
- package/styles/components/_dropdown.scss +72 -72
- package/styles/components/_form.scss +1583 -1583
|
@@ -1,481 +1,481 @@
|
|
|
1
|
-
import React, { useContext, useEffect } from "react";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
AirlineBookingPackageOption,
|
|
5
|
-
AirportBookingPackageOption,
|
|
6
|
-
BookingAirlineGroup,
|
|
7
|
-
BookingAirportGroup,
|
|
8
|
-
BookingOptionGroup,
|
|
9
|
-
BookingOptionPax,
|
|
10
|
-
BookingOptionUnit,
|
|
11
|
-
BookingPackageFlight,
|
|
12
|
-
Pax,
|
|
13
|
-
PerBookingPackageOption,
|
|
14
|
-
} from "@qite/tide-client/build/types";
|
|
15
|
-
import { Link, navigate } from "@reach/router";
|
|
16
|
-
import { isEmpty } from "lodash";
|
|
17
|
-
import { useSelector } from "react-redux";
|
|
18
|
-
import { buildClassName } from "../../../shared/utils/class-util";
|
|
19
|
-
import SettingsContext from "../../settings-context";
|
|
20
|
-
import { useAppDispatch } from "../../store";
|
|
21
|
-
import {
|
|
22
|
-
setCurrentStep,
|
|
23
|
-
setPackage,
|
|
24
|
-
setPackageAirlineGroups,
|
|
25
|
-
setPackageAirportGroups,
|
|
26
|
-
setPackageGroups,
|
|
27
|
-
setPackageOptionPax,
|
|
28
|
-
setPackageOptionUnits,
|
|
29
|
-
setPackageRooms,
|
|
30
|
-
setTagIds,
|
|
31
|
-
} from "../booking/booking-slice";
|
|
32
|
-
import {
|
|
33
|
-
FLIGHT_OPTIONS_FORM_STEP,
|
|
34
|
-
ROOM_OPTIONS_FORM_STEP,
|
|
35
|
-
TRAVELERS_FORM_STEP,
|
|
36
|
-
} from "../booking/constants";
|
|
37
|
-
import {
|
|
38
|
-
selectAvailabilities,
|
|
39
|
-
selectBookingPackagePax,
|
|
40
|
-
selectBookingQueryString,
|
|
41
|
-
selectIsFetchingProductOptions,
|
|
42
|
-
selectPackageAirlineGroups,
|
|
43
|
-
selectPackageAirportGroups,
|
|
44
|
-
selectPackageDetails,
|
|
45
|
-
selectPackageGroups,
|
|
46
|
-
selectPackageOptionPax,
|
|
47
|
-
selectPackageOptionUnits,
|
|
48
|
-
selectPackageRooms,
|
|
49
|
-
selectPackageTags,
|
|
50
|
-
selectRequestRooms,
|
|
51
|
-
selectTagIds,
|
|
52
|
-
selectTranslations,
|
|
53
|
-
} from "../booking/selectors";
|
|
54
|
-
import { fetchPriceDetails } from "../price-details/price-details-slice";
|
|
55
|
-
import { updatePackageRooms } from "../room-options/room-utils";
|
|
56
|
-
import NoOptions from "./no-options";
|
|
57
|
-
import OptionBookingAirlineGroup from "./option-booking-airline-group";
|
|
58
|
-
import OptionBookingGroup from "./option-booking-group";
|
|
59
|
-
import OptionPaxCard from "./option-pax-card";
|
|
60
|
-
import OptionRoom from "./option-room";
|
|
61
|
-
import OptionUnitsCard from "./option-units-card";
|
|
62
|
-
import PrintOfferButton from "../../components/print-offer-button";
|
|
63
|
-
|
|
64
|
-
interface OptionsFormProps {}
|
|
65
|
-
|
|
66
|
-
const OptionsForm: React.FC<OptionsFormProps> = () => {
|
|
67
|
-
const settings = useContext(SettingsContext);
|
|
68
|
-
const { token } = settings;
|
|
69
|
-
const translations = useSelector(selectTranslations);
|
|
70
|
-
const dispatch = useAppDispatch();
|
|
71
|
-
const packageDetails = useSelector(selectPackageDetails);
|
|
72
|
-
const requestRooms = useSelector(selectRequestRooms);
|
|
73
|
-
const requestRoomsPax = requestRooms?.flatMap((x) => x.pax);
|
|
74
|
-
const bookingQueryString = useSelector(selectBookingQueryString);
|
|
75
|
-
const isLoading = useSelector(selectIsFetchingProductOptions);
|
|
76
|
-
|
|
77
|
-
const groups = useSelector(selectPackageGroups);
|
|
78
|
-
const airlineGroups = useSelector(selectPackageAirlineGroups);
|
|
79
|
-
const airportGroups = useSelector(selectPackageAirportGroups);
|
|
80
|
-
const optionUnits = useSelector(selectPackageOptionUnits);
|
|
81
|
-
const optionPax = useSelector(selectPackageOptionPax);
|
|
82
|
-
const availabilities = useSelector(selectAvailabilities);
|
|
83
|
-
|
|
84
|
-
// ROOMS
|
|
85
|
-
const showRoomOptions = settings.roomOptions.isHidden;
|
|
86
|
-
const packageRooms = useSelector(selectPackageRooms);
|
|
87
|
-
const pax = useSelector(selectBookingPackagePax);
|
|
88
|
-
|
|
89
|
-
const getRoomPax = (index: number) => {
|
|
90
|
-
var room = requestRooms?.find((x) => x.index == index);
|
|
91
|
-
var bookingPackagePax = pax.filter((x) =>
|
|
92
|
-
room?.pax.some((y) => y.id == x.id)
|
|
93
|
-
);
|
|
94
|
-
return bookingPackagePax.length > 0 ? bookingPackagePax : room?.pax ?? [];
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
const handleOnRoomChange = (
|
|
98
|
-
index: number,
|
|
99
|
-
accommodationCode: string,
|
|
100
|
-
regimeCode: string | null
|
|
101
|
-
) => {
|
|
102
|
-
if (!packageRooms) return;
|
|
103
|
-
|
|
104
|
-
const updatedPackageRooms = updatePackageRooms(
|
|
105
|
-
packageRooms,
|
|
106
|
-
index,
|
|
107
|
-
accommodationCode,
|
|
108
|
-
regimeCode,
|
|
109
|
-
availabilities!
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
dispatch(setPackageRooms(updatedPackageRooms));
|
|
113
|
-
dispatch(fetchPriceDetails());
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const getPax = () => {
|
|
117
|
-
if (!packageDetails) return undefined;
|
|
118
|
-
const selectedOption =
|
|
119
|
-
packageDetails.options.find((o) => o.isSelected) ??
|
|
120
|
-
packageDetails.options[0];
|
|
121
|
-
return selectedOption?.requestRooms.flatMap((r) => r.pax) as Pax[];
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
// TAGS
|
|
125
|
-
const packageTags = settings.hideTags ? [] : useSelector(selectPackageTags);
|
|
126
|
-
let tagIds = useSelector(selectTagIds) ?? [];
|
|
127
|
-
|
|
128
|
-
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (e) => {
|
|
129
|
-
if (settings.skipRouter) {
|
|
130
|
-
dispatch(setCurrentStep(TRAVELERS_FORM_STEP));
|
|
131
|
-
} else {
|
|
132
|
-
navigate(
|
|
133
|
-
`${settings.basePath}${settings.travellers.pathSuffix}?${bookingQueryString}`
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
e.preventDefault();
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
const handleOnPaxChange = (pax: BookingOptionPax[]) => {
|
|
141
|
-
dispatch(setPackageOptionPax(pax));
|
|
142
|
-
dispatch(fetchPriceDetails());
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const handleOnUnitsChange = (units: BookingOptionUnit[]) => {
|
|
146
|
-
dispatch(setPackageOptionUnits(units));
|
|
147
|
-
dispatch(fetchPriceDetails());
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
const handleOnGroupChange = (
|
|
151
|
-
group: BookingOptionGroup<PerBookingPackageOption>
|
|
152
|
-
) => {
|
|
153
|
-
if (groups) {
|
|
154
|
-
const updatedGroups = groups?.map((g) =>
|
|
155
|
-
g.name === group.name ? group : g
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
dispatch(setPackageGroups(updatedGroups));
|
|
159
|
-
dispatch(fetchPriceDetails());
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const handleOnAirlineGroupChange = (
|
|
164
|
-
group: BookingAirlineGroup<AirlineBookingPackageOption>
|
|
165
|
-
) => {
|
|
166
|
-
if (airlineGroups) {
|
|
167
|
-
const updatedGroups = airlineGroups.map((g) =>
|
|
168
|
-
g.label === group.label ? group : g
|
|
169
|
-
);
|
|
170
|
-
|
|
171
|
-
dispatch(setPackageAirlineGroups(updatedGroups));
|
|
172
|
-
dispatch(fetchPriceDetails());
|
|
173
|
-
}
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
const handleOnAirportGroupChange = (
|
|
177
|
-
group: BookingAirportGroup<AirportBookingPackageOption>
|
|
178
|
-
) => {
|
|
179
|
-
if (airportGroups) {
|
|
180
|
-
const updatedGroups = airportGroups.map((g) =>
|
|
181
|
-
g.label === group.label ? group : g
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
dispatch(setPackageAirportGroups(updatedGroups));
|
|
185
|
-
dispatch(fetchPriceDetails());
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
const handleOnTagChange = (id: number, checked: boolean) => {
|
|
190
|
-
let updatedTags = [...tagIds];
|
|
191
|
-
if (checked) {
|
|
192
|
-
if (!updatedTags?.includes(id)) {
|
|
193
|
-
updatedTags?.push(id);
|
|
194
|
-
}
|
|
195
|
-
} else {
|
|
196
|
-
updatedTags = updatedTags?.filter((x) => x != id);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
dispatch(setTagIds(updatedTags));
|
|
200
|
-
dispatch(fetchPriceDetails());
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
useEffect(() => {
|
|
204
|
-
if (
|
|
205
|
-
packageDetails &&
|
|
206
|
-
settings.roomOptions.isHidden &&
|
|
207
|
-
settings.flightOptions.isHidden
|
|
208
|
-
) {
|
|
209
|
-
const params = new URLSearchParams(location.search);
|
|
210
|
-
|
|
211
|
-
const outwardFlight = params.get("outwardflight") ?? undefined;
|
|
212
|
-
const returnFlight = params.get("returnflight") ?? undefined;
|
|
213
|
-
if (outwardFlight && returnFlight) {
|
|
214
|
-
const desiredOutwardFlight = packageDetails.outwardFlights.find(
|
|
215
|
-
(x) => x.entryLineGuid == outwardFlight
|
|
216
|
-
);
|
|
217
|
-
const desiredReturnFlight = packageDetails.returnFlights.find(
|
|
218
|
-
(x) => x.entryLineGuid == returnFlight
|
|
219
|
-
);
|
|
220
|
-
if (desiredOutwardFlight && desiredReturnFlight) {
|
|
221
|
-
dispatch(
|
|
222
|
-
setPackage({
|
|
223
|
-
...packageDetails,
|
|
224
|
-
outwardFlights: packageDetails.outwardFlights.map((flight) => {
|
|
225
|
-
return {
|
|
226
|
-
...flight,
|
|
227
|
-
isSelected:
|
|
228
|
-
flight.entryLineGuid == desiredOutwardFlight.entryLineGuid
|
|
229
|
-
? true
|
|
230
|
-
: false,
|
|
231
|
-
} as BookingPackageFlight;
|
|
232
|
-
}),
|
|
233
|
-
returnFlights: packageDetails.returnFlights.map((flight) => {
|
|
234
|
-
return {
|
|
235
|
-
...flight,
|
|
236
|
-
isSelected:
|
|
237
|
-
flight.entryLineGuid == desiredReturnFlight.entryLineGuid
|
|
238
|
-
? true
|
|
239
|
-
: false,
|
|
240
|
-
} as BookingPackageFlight;
|
|
241
|
-
}),
|
|
242
|
-
})
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
dispatch(fetchPriceDetails());
|
|
248
|
-
}, []);
|
|
249
|
-
|
|
250
|
-
const goPrevious = () => {
|
|
251
|
-
if (settings.roomOptions.isHidden) {
|
|
252
|
-
dispatch(setCurrentStep(FLIGHT_OPTIONS_FORM_STEP));
|
|
253
|
-
} else {
|
|
254
|
-
dispatch(setCurrentStep(ROOM_OPTIONS_FORM_STEP));
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
const previousUrl = settings.roomOptions.isHidden
|
|
259
|
-
? `${settings.basePath}${settings.flightOptions.pathSuffix}?${bookingQueryString}`
|
|
260
|
-
: `${settings.basePath}${settings.roomOptions.pathSuffix}?${bookingQueryString}`;
|
|
261
|
-
const hasPrevious =
|
|
262
|
-
!settings.roomOptions.isHidden || !settings.flightOptions.isHidden;
|
|
263
|
-
const showPackageTagsOrRoomoptions =
|
|
264
|
-
showRoomOptions || (packageTags && !isEmpty(packageTags));
|
|
265
|
-
|
|
266
|
-
return (
|
|
267
|
-
<>
|
|
268
|
-
<form
|
|
269
|
-
className="form"
|
|
270
|
-
name="booking--options"
|
|
271
|
-
id="booking--options"
|
|
272
|
-
noValidate
|
|
273
|
-
onSubmit={handleSubmit}
|
|
274
|
-
>
|
|
275
|
-
{isLoading && settings.loaderComponent}
|
|
276
|
-
{!isLoading && (
|
|
277
|
-
<div className="form__region">
|
|
278
|
-
{showPackageTagsOrRoomoptions && (
|
|
279
|
-
<div className="form__group">
|
|
280
|
-
<div className="booking-card">
|
|
281
|
-
<div className="booking-card__body">
|
|
282
|
-
<div
|
|
283
|
-
className={buildClassName([
|
|
284
|
-
"booking-card__group",
|
|
285
|
-
"booking-card__group--package",
|
|
286
|
-
])}
|
|
287
|
-
>
|
|
288
|
-
{showRoomOptions && (
|
|
289
|
-
<span className="booking-card__tag">
|
|
290
|
-
{translations.OPTIONS_FORM.PACKAGE}
|
|
291
|
-
</span>
|
|
292
|
-
)}
|
|
293
|
-
<div className="booking-card__group-body">
|
|
294
|
-
{showRoomOptions && (
|
|
295
|
-
<table className="table table--striped">
|
|
296
|
-
<tbody>
|
|
297
|
-
{packageRooms &&
|
|
298
|
-
packageRooms.map((room) => (
|
|
299
|
-
<OptionRoom
|
|
300
|
-
key={room.index}
|
|
301
|
-
packageRoom={room}
|
|
302
|
-
pax={getRoomPax(room.index)}
|
|
303
|
-
optionPax={optionPax}
|
|
304
|
-
onRoomChange={handleOnRoomChange}
|
|
305
|
-
/>
|
|
306
|
-
))}
|
|
307
|
-
</tbody>
|
|
308
|
-
</table>
|
|
309
|
-
)}
|
|
310
|
-
{packageTags && !isEmpty(packageTags) && (
|
|
311
|
-
<div className="booking-card__tag-translations">
|
|
312
|
-
{packageTags.map((tag, index) => (
|
|
313
|
-
<label
|
|
314
|
-
key={index}
|
|
315
|
-
htmlFor={`tag-translation-${index}-${tag.title}`}
|
|
316
|
-
className="checkbox__label tag-translation"
|
|
317
|
-
>
|
|
318
|
-
<div className="tag-translation-input__container">
|
|
319
|
-
<input
|
|
320
|
-
type="checkbox"
|
|
321
|
-
id={`tag-translation-${index}-${tag.title}`}
|
|
322
|
-
name={`tag-translation-${index}-${tag.title}`}
|
|
323
|
-
className="checkbox__input"
|
|
324
|
-
checked={tagIds?.includes(tag.id)}
|
|
325
|
-
onChange={(e) =>
|
|
326
|
-
handleOnTagChange(
|
|
327
|
-
tag.id,
|
|
328
|
-
e.target.checked
|
|
329
|
-
)
|
|
330
|
-
}
|
|
331
|
-
/>
|
|
332
|
-
</div>
|
|
333
|
-
<span className="tag-translation__title">
|
|
334
|
-
{tag.title}
|
|
335
|
-
</span>
|
|
336
|
-
|
|
337
|
-
<span className="tag-translation__description">
|
|
338
|
-
{tag.description}
|
|
339
|
-
</span>
|
|
340
|
-
</label>
|
|
341
|
-
))}
|
|
342
|
-
</div>
|
|
343
|
-
)}
|
|
344
|
-
</div>
|
|
345
|
-
</div>
|
|
346
|
-
</div>
|
|
347
|
-
</div>
|
|
348
|
-
</div>
|
|
349
|
-
)}
|
|
350
|
-
{optionUnits && !isEmpty(optionUnits) && (
|
|
351
|
-
<div className="form__group">
|
|
352
|
-
<div className="booking-card">
|
|
353
|
-
<div className="booking-card__header">
|
|
354
|
-
<h2 className="booking-card__header-heading">
|
|
355
|
-
{translations.OPTIONS_FORM.PER_UNIT_TITLE}
|
|
356
|
-
</h2>
|
|
357
|
-
</div>
|
|
358
|
-
<div className="booking-card__body">
|
|
359
|
-
<OptionUnitsCard
|
|
360
|
-
units={optionUnits}
|
|
361
|
-
onUnitsChange={handleOnUnitsChange}
|
|
362
|
-
/>
|
|
363
|
-
</div>
|
|
364
|
-
</div>
|
|
365
|
-
</div>
|
|
366
|
-
)}
|
|
367
|
-
|
|
368
|
-
{optionPax && !isEmpty(optionPax) && (
|
|
369
|
-
<div className="form__group">
|
|
370
|
-
<div className="booking-card">
|
|
371
|
-
<div className="booking-card__header">
|
|
372
|
-
<h2 className="booking-card__header-heading">
|
|
373
|
-
{translations.OPTIONS_FORM.PER_PAX_TITLE}
|
|
374
|
-
</h2>
|
|
375
|
-
</div>
|
|
376
|
-
<div className="booking-card__body">
|
|
377
|
-
<OptionPaxCard
|
|
378
|
-
pax={optionPax}
|
|
379
|
-
onPaxChange={handleOnPaxChange}
|
|
380
|
-
requestRoomsPax={requestRoomsPax}
|
|
381
|
-
/>
|
|
382
|
-
</div>
|
|
383
|
-
</div>
|
|
384
|
-
</div>
|
|
385
|
-
)}
|
|
386
|
-
|
|
387
|
-
{groups && !isEmpty(groups) && (
|
|
388
|
-
<div className="form__group">
|
|
389
|
-
<div className="booking-card">
|
|
390
|
-
<div className="booking-card__header">
|
|
391
|
-
<h2 className="booking-card__header-heading">
|
|
392
|
-
{translations.OPTIONS_FORM.PER_BOOKING_TITLE}
|
|
393
|
-
</h2>
|
|
394
|
-
</div>
|
|
395
|
-
<div className="booking-card__body">
|
|
396
|
-
<div className="booking-card__group booking-card__group--active">
|
|
397
|
-
{groups.map((group, i) => (
|
|
398
|
-
<OptionBookingGroup
|
|
399
|
-
key={`${group.name}_${i}`}
|
|
400
|
-
group={group}
|
|
401
|
-
firstClassName={"booking-card__group-body"}
|
|
402
|
-
secondClassName={"booking-card__group-heading"}
|
|
403
|
-
parentId={`booking_${group.name}`}
|
|
404
|
-
onGroupChange={handleOnGroupChange}
|
|
405
|
-
/>
|
|
406
|
-
))}
|
|
407
|
-
{airlineGroups?.map((group, i) => (
|
|
408
|
-
<OptionBookingAirlineGroup
|
|
409
|
-
key={`${group.label}_${i}`}
|
|
410
|
-
airGroup={group}
|
|
411
|
-
onGroupChange={handleOnAirlineGroupChange}
|
|
412
|
-
/>
|
|
413
|
-
))}
|
|
414
|
-
{airportGroups?.map((group, i) => (
|
|
415
|
-
<OptionBookingAirlineGroup
|
|
416
|
-
key={`${group.label}_${i}`}
|
|
417
|
-
airGroup={group}
|
|
418
|
-
onGroupChange={handleOnAirportGroupChange}
|
|
419
|
-
/>
|
|
420
|
-
))}
|
|
421
|
-
</div>
|
|
422
|
-
</div>
|
|
423
|
-
</div>
|
|
424
|
-
</div>
|
|
425
|
-
)}
|
|
426
|
-
|
|
427
|
-
{isEmpty(groups) && isEmpty(optionUnits) && isEmpty(optionPax) && (
|
|
428
|
-
<NoOptions />
|
|
429
|
-
)}
|
|
430
|
-
</div>
|
|
431
|
-
)}
|
|
432
|
-
<div className="booking__navigator">
|
|
433
|
-
{hasPrevious && (
|
|
434
|
-
<>
|
|
435
|
-
{settings.skipRouter ? (
|
|
436
|
-
<button
|
|
437
|
-
type="button"
|
|
438
|
-
title={translations.STEPS.PREVIOUS}
|
|
439
|
-
onClick={() => goPrevious()}
|
|
440
|
-
className="cta cta--secondary"
|
|
441
|
-
>
|
|
442
|
-
{translations.STEPS.PREVIOUS}
|
|
443
|
-
</button>
|
|
444
|
-
) : (
|
|
445
|
-
<Link
|
|
446
|
-
to={previousUrl}
|
|
447
|
-
title={translations.STEPS.PREVIOUS}
|
|
448
|
-
className="cta cta--secondary"
|
|
449
|
-
>
|
|
450
|
-
{translations.STEPS.PREVIOUS}
|
|
451
|
-
</Link>
|
|
452
|
-
)}
|
|
453
|
-
</>
|
|
454
|
-
)}
|
|
455
|
-
{token && settings.options.reportPrintActionId && (
|
|
456
|
-
<PrintOfferButton
|
|
457
|
-
bookingPackage={packageDetails}
|
|
458
|
-
getPax={getPax}
|
|
459
|
-
tagIds={tagIds}
|
|
460
|
-
printActionId={settings.options.reportPrintActionId}
|
|
461
|
-
labelIdle={translations.PRINT_OFFER_BUTTON.LABEL_IDLE}
|
|
462
|
-
labelCreating={translations.PRINT_OFFER_BUTTON.LABEL_CREATING}
|
|
463
|
-
labelPrinting={translations.PRINT_OFFER_BUTTON.LABEL_PRINTING}
|
|
464
|
-
className="cta spinner-button"
|
|
465
|
-
/>
|
|
466
|
-
)}
|
|
467
|
-
<button
|
|
468
|
-
type="submit"
|
|
469
|
-
title={translations.STEPS.NEXT}
|
|
470
|
-
disabled={isLoading}
|
|
471
|
-
className={buildClassName(["cta", isLoading && "cta--disabled"])}
|
|
472
|
-
>
|
|
473
|
-
{translations.STEPS.NEXT}
|
|
474
|
-
</button>
|
|
475
|
-
</div>
|
|
476
|
-
</form>
|
|
477
|
-
</>
|
|
478
|
-
);
|
|
479
|
-
};
|
|
480
|
-
|
|
481
|
-
export default OptionsForm;
|
|
1
|
+
import React, { useContext, useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AirlineBookingPackageOption,
|
|
5
|
+
AirportBookingPackageOption,
|
|
6
|
+
BookingAirlineGroup,
|
|
7
|
+
BookingAirportGroup,
|
|
8
|
+
BookingOptionGroup,
|
|
9
|
+
BookingOptionPax,
|
|
10
|
+
BookingOptionUnit,
|
|
11
|
+
BookingPackageFlight,
|
|
12
|
+
Pax,
|
|
13
|
+
PerBookingPackageOption,
|
|
14
|
+
} from "@qite/tide-client/build/types";
|
|
15
|
+
import { Link, navigate } from "@reach/router";
|
|
16
|
+
import { isEmpty } from "lodash";
|
|
17
|
+
import { useSelector } from "react-redux";
|
|
18
|
+
import { buildClassName } from "../../../shared/utils/class-util";
|
|
19
|
+
import SettingsContext from "../../settings-context";
|
|
20
|
+
import { useAppDispatch } from "../../store";
|
|
21
|
+
import {
|
|
22
|
+
setCurrentStep,
|
|
23
|
+
setPackage,
|
|
24
|
+
setPackageAirlineGroups,
|
|
25
|
+
setPackageAirportGroups,
|
|
26
|
+
setPackageGroups,
|
|
27
|
+
setPackageOptionPax,
|
|
28
|
+
setPackageOptionUnits,
|
|
29
|
+
setPackageRooms,
|
|
30
|
+
setTagIds,
|
|
31
|
+
} from "../booking/booking-slice";
|
|
32
|
+
import {
|
|
33
|
+
FLIGHT_OPTIONS_FORM_STEP,
|
|
34
|
+
ROOM_OPTIONS_FORM_STEP,
|
|
35
|
+
TRAVELERS_FORM_STEP,
|
|
36
|
+
} from "../booking/constants";
|
|
37
|
+
import {
|
|
38
|
+
selectAvailabilities,
|
|
39
|
+
selectBookingPackagePax,
|
|
40
|
+
selectBookingQueryString,
|
|
41
|
+
selectIsFetchingProductOptions,
|
|
42
|
+
selectPackageAirlineGroups,
|
|
43
|
+
selectPackageAirportGroups,
|
|
44
|
+
selectPackageDetails,
|
|
45
|
+
selectPackageGroups,
|
|
46
|
+
selectPackageOptionPax,
|
|
47
|
+
selectPackageOptionUnits,
|
|
48
|
+
selectPackageRooms,
|
|
49
|
+
selectPackageTags,
|
|
50
|
+
selectRequestRooms,
|
|
51
|
+
selectTagIds,
|
|
52
|
+
selectTranslations,
|
|
53
|
+
} from "../booking/selectors";
|
|
54
|
+
import { fetchPriceDetails } from "../price-details/price-details-slice";
|
|
55
|
+
import { updatePackageRooms } from "../room-options/room-utils";
|
|
56
|
+
import NoOptions from "./no-options";
|
|
57
|
+
import OptionBookingAirlineGroup from "./option-booking-airline-group";
|
|
58
|
+
import OptionBookingGroup from "./option-booking-group";
|
|
59
|
+
import OptionPaxCard from "./option-pax-card";
|
|
60
|
+
import OptionRoom from "./option-room";
|
|
61
|
+
import OptionUnitsCard from "./option-units-card";
|
|
62
|
+
import PrintOfferButton from "../../components/print-offer-button";
|
|
63
|
+
|
|
64
|
+
interface OptionsFormProps {}
|
|
65
|
+
|
|
66
|
+
const OptionsForm: React.FC<OptionsFormProps> = () => {
|
|
67
|
+
const settings = useContext(SettingsContext);
|
|
68
|
+
const { token } = settings;
|
|
69
|
+
const translations = useSelector(selectTranslations);
|
|
70
|
+
const dispatch = useAppDispatch();
|
|
71
|
+
const packageDetails = useSelector(selectPackageDetails);
|
|
72
|
+
const requestRooms = useSelector(selectRequestRooms);
|
|
73
|
+
const requestRoomsPax = requestRooms?.flatMap((x) => x.pax);
|
|
74
|
+
const bookingQueryString = useSelector(selectBookingQueryString);
|
|
75
|
+
const isLoading = useSelector(selectIsFetchingProductOptions);
|
|
76
|
+
|
|
77
|
+
const groups = useSelector(selectPackageGroups);
|
|
78
|
+
const airlineGroups = useSelector(selectPackageAirlineGroups);
|
|
79
|
+
const airportGroups = useSelector(selectPackageAirportGroups);
|
|
80
|
+
const optionUnits = useSelector(selectPackageOptionUnits);
|
|
81
|
+
const optionPax = useSelector(selectPackageOptionPax);
|
|
82
|
+
const availabilities = useSelector(selectAvailabilities);
|
|
83
|
+
|
|
84
|
+
// ROOMS
|
|
85
|
+
const showRoomOptions = settings.roomOptions.isHidden;
|
|
86
|
+
const packageRooms = useSelector(selectPackageRooms);
|
|
87
|
+
const pax = useSelector(selectBookingPackagePax);
|
|
88
|
+
|
|
89
|
+
const getRoomPax = (index: number) => {
|
|
90
|
+
var room = requestRooms?.find((x) => x.index == index);
|
|
91
|
+
var bookingPackagePax = pax.filter((x) =>
|
|
92
|
+
room?.pax.some((y) => y.id == x.id)
|
|
93
|
+
);
|
|
94
|
+
return bookingPackagePax.length > 0 ? bookingPackagePax : room?.pax ?? [];
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const handleOnRoomChange = (
|
|
98
|
+
index: number,
|
|
99
|
+
accommodationCode: string,
|
|
100
|
+
regimeCode: string | null
|
|
101
|
+
) => {
|
|
102
|
+
if (!packageRooms) return;
|
|
103
|
+
|
|
104
|
+
const updatedPackageRooms = updatePackageRooms(
|
|
105
|
+
packageRooms,
|
|
106
|
+
index,
|
|
107
|
+
accommodationCode,
|
|
108
|
+
regimeCode,
|
|
109
|
+
availabilities!
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
dispatch(setPackageRooms(updatedPackageRooms));
|
|
113
|
+
dispatch(fetchPriceDetails());
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const getPax = () => {
|
|
117
|
+
if (!packageDetails) return undefined;
|
|
118
|
+
const selectedOption =
|
|
119
|
+
packageDetails.options.find((o) => o.isSelected) ??
|
|
120
|
+
packageDetails.options[0];
|
|
121
|
+
return selectedOption?.requestRooms.flatMap((r) => r.pax) as Pax[];
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// TAGS
|
|
125
|
+
const packageTags = settings.hideTags ? [] : useSelector(selectPackageTags);
|
|
126
|
+
let tagIds = useSelector(selectTagIds) ?? [];
|
|
127
|
+
|
|
128
|
+
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (e) => {
|
|
129
|
+
if (settings.skipRouter) {
|
|
130
|
+
dispatch(setCurrentStep(TRAVELERS_FORM_STEP));
|
|
131
|
+
} else {
|
|
132
|
+
navigate(
|
|
133
|
+
`${settings.basePath}${settings.travellers.pathSuffix}?${bookingQueryString}`
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
e.preventDefault();
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const handleOnPaxChange = (pax: BookingOptionPax[]) => {
|
|
141
|
+
dispatch(setPackageOptionPax(pax));
|
|
142
|
+
dispatch(fetchPriceDetails());
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const handleOnUnitsChange = (units: BookingOptionUnit[]) => {
|
|
146
|
+
dispatch(setPackageOptionUnits(units));
|
|
147
|
+
dispatch(fetchPriceDetails());
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const handleOnGroupChange = (
|
|
151
|
+
group: BookingOptionGroup<PerBookingPackageOption>
|
|
152
|
+
) => {
|
|
153
|
+
if (groups) {
|
|
154
|
+
const updatedGroups = groups?.map((g) =>
|
|
155
|
+
g.name === group.name ? group : g
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
dispatch(setPackageGroups(updatedGroups));
|
|
159
|
+
dispatch(fetchPriceDetails());
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const handleOnAirlineGroupChange = (
|
|
164
|
+
group: BookingAirlineGroup<AirlineBookingPackageOption>
|
|
165
|
+
) => {
|
|
166
|
+
if (airlineGroups) {
|
|
167
|
+
const updatedGroups = airlineGroups.map((g) =>
|
|
168
|
+
g.label === group.label ? group : g
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
dispatch(setPackageAirlineGroups(updatedGroups));
|
|
172
|
+
dispatch(fetchPriceDetails());
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const handleOnAirportGroupChange = (
|
|
177
|
+
group: BookingAirportGroup<AirportBookingPackageOption>
|
|
178
|
+
) => {
|
|
179
|
+
if (airportGroups) {
|
|
180
|
+
const updatedGroups = airportGroups.map((g) =>
|
|
181
|
+
g.label === group.label ? group : g
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
dispatch(setPackageAirportGroups(updatedGroups));
|
|
185
|
+
dispatch(fetchPriceDetails());
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const handleOnTagChange = (id: number, checked: boolean) => {
|
|
190
|
+
let updatedTags = [...tagIds];
|
|
191
|
+
if (checked) {
|
|
192
|
+
if (!updatedTags?.includes(id)) {
|
|
193
|
+
updatedTags?.push(id);
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
updatedTags = updatedTags?.filter((x) => x != id);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
dispatch(setTagIds(updatedTags));
|
|
200
|
+
dispatch(fetchPriceDetails());
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
useEffect(() => {
|
|
204
|
+
if (
|
|
205
|
+
packageDetails &&
|
|
206
|
+
settings.roomOptions.isHidden &&
|
|
207
|
+
settings.flightOptions.isHidden
|
|
208
|
+
) {
|
|
209
|
+
const params = new URLSearchParams(location.search);
|
|
210
|
+
|
|
211
|
+
const outwardFlight = params.get("outwardflight") ?? undefined;
|
|
212
|
+
const returnFlight = params.get("returnflight") ?? undefined;
|
|
213
|
+
if (outwardFlight && returnFlight) {
|
|
214
|
+
const desiredOutwardFlight = packageDetails.outwardFlights.find(
|
|
215
|
+
(x) => x.entryLineGuid == outwardFlight
|
|
216
|
+
);
|
|
217
|
+
const desiredReturnFlight = packageDetails.returnFlights.find(
|
|
218
|
+
(x) => x.entryLineGuid == returnFlight
|
|
219
|
+
);
|
|
220
|
+
if (desiredOutwardFlight && desiredReturnFlight) {
|
|
221
|
+
dispatch(
|
|
222
|
+
setPackage({
|
|
223
|
+
...packageDetails,
|
|
224
|
+
outwardFlights: packageDetails.outwardFlights.map((flight) => {
|
|
225
|
+
return {
|
|
226
|
+
...flight,
|
|
227
|
+
isSelected:
|
|
228
|
+
flight.entryLineGuid == desiredOutwardFlight.entryLineGuid
|
|
229
|
+
? true
|
|
230
|
+
: false,
|
|
231
|
+
} as BookingPackageFlight;
|
|
232
|
+
}),
|
|
233
|
+
returnFlights: packageDetails.returnFlights.map((flight) => {
|
|
234
|
+
return {
|
|
235
|
+
...flight,
|
|
236
|
+
isSelected:
|
|
237
|
+
flight.entryLineGuid == desiredReturnFlight.entryLineGuid
|
|
238
|
+
? true
|
|
239
|
+
: false,
|
|
240
|
+
} as BookingPackageFlight;
|
|
241
|
+
}),
|
|
242
|
+
})
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
dispatch(fetchPriceDetails());
|
|
248
|
+
}, []);
|
|
249
|
+
|
|
250
|
+
const goPrevious = () => {
|
|
251
|
+
if (settings.roomOptions.isHidden) {
|
|
252
|
+
dispatch(setCurrentStep(FLIGHT_OPTIONS_FORM_STEP));
|
|
253
|
+
} else {
|
|
254
|
+
dispatch(setCurrentStep(ROOM_OPTIONS_FORM_STEP));
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const previousUrl = settings.roomOptions.isHidden
|
|
259
|
+
? `${settings.basePath}${settings.flightOptions.pathSuffix}?${bookingQueryString}`
|
|
260
|
+
: `${settings.basePath}${settings.roomOptions.pathSuffix}?${bookingQueryString}`;
|
|
261
|
+
const hasPrevious =
|
|
262
|
+
!settings.roomOptions.isHidden || !settings.flightOptions.isHidden;
|
|
263
|
+
const showPackageTagsOrRoomoptions =
|
|
264
|
+
showRoomOptions || (packageTags && !isEmpty(packageTags));
|
|
265
|
+
|
|
266
|
+
return (
|
|
267
|
+
<>
|
|
268
|
+
<form
|
|
269
|
+
className="form"
|
|
270
|
+
name="booking--options"
|
|
271
|
+
id="booking--options"
|
|
272
|
+
noValidate
|
|
273
|
+
onSubmit={handleSubmit}
|
|
274
|
+
>
|
|
275
|
+
{isLoading && settings.loaderComponent}
|
|
276
|
+
{!isLoading && (
|
|
277
|
+
<div className="form__region">
|
|
278
|
+
{showPackageTagsOrRoomoptions && (
|
|
279
|
+
<div className="form__group">
|
|
280
|
+
<div className="booking-card">
|
|
281
|
+
<div className="booking-card__body">
|
|
282
|
+
<div
|
|
283
|
+
className={buildClassName([
|
|
284
|
+
"booking-card__group",
|
|
285
|
+
"booking-card__group--package",
|
|
286
|
+
])}
|
|
287
|
+
>
|
|
288
|
+
{showRoomOptions && (
|
|
289
|
+
<span className="booking-card__tag">
|
|
290
|
+
{translations.OPTIONS_FORM.PACKAGE}
|
|
291
|
+
</span>
|
|
292
|
+
)}
|
|
293
|
+
<div className="booking-card__group-body">
|
|
294
|
+
{showRoomOptions && (
|
|
295
|
+
<table className="table table--striped">
|
|
296
|
+
<tbody>
|
|
297
|
+
{packageRooms &&
|
|
298
|
+
packageRooms.map((room) => (
|
|
299
|
+
<OptionRoom
|
|
300
|
+
key={room.index}
|
|
301
|
+
packageRoom={room}
|
|
302
|
+
pax={getRoomPax(room.index)}
|
|
303
|
+
optionPax={optionPax}
|
|
304
|
+
onRoomChange={handleOnRoomChange}
|
|
305
|
+
/>
|
|
306
|
+
))}
|
|
307
|
+
</tbody>
|
|
308
|
+
</table>
|
|
309
|
+
)}
|
|
310
|
+
{packageTags && !isEmpty(packageTags) && (
|
|
311
|
+
<div className="booking-card__tag-translations">
|
|
312
|
+
{packageTags.map((tag, index) => (
|
|
313
|
+
<label
|
|
314
|
+
key={index}
|
|
315
|
+
htmlFor={`tag-translation-${index}-${tag.title}`}
|
|
316
|
+
className="checkbox__label tag-translation"
|
|
317
|
+
>
|
|
318
|
+
<div className="tag-translation-input__container">
|
|
319
|
+
<input
|
|
320
|
+
type="checkbox"
|
|
321
|
+
id={`tag-translation-${index}-${tag.title}`}
|
|
322
|
+
name={`tag-translation-${index}-${tag.title}`}
|
|
323
|
+
className="checkbox__input"
|
|
324
|
+
checked={tagIds?.includes(tag.id)}
|
|
325
|
+
onChange={(e) =>
|
|
326
|
+
handleOnTagChange(
|
|
327
|
+
tag.id,
|
|
328
|
+
e.target.checked
|
|
329
|
+
)
|
|
330
|
+
}
|
|
331
|
+
/>
|
|
332
|
+
</div>
|
|
333
|
+
<span className="tag-translation__title">
|
|
334
|
+
{tag.title}
|
|
335
|
+
</span>
|
|
336
|
+
|
|
337
|
+
<span className="tag-translation__description">
|
|
338
|
+
{tag.description}
|
|
339
|
+
</span>
|
|
340
|
+
</label>
|
|
341
|
+
))}
|
|
342
|
+
</div>
|
|
343
|
+
)}
|
|
344
|
+
</div>
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
</div>
|
|
349
|
+
)}
|
|
350
|
+
{optionUnits && !isEmpty(optionUnits) && (
|
|
351
|
+
<div className="form__group">
|
|
352
|
+
<div className="booking-card">
|
|
353
|
+
<div className="booking-card__header">
|
|
354
|
+
<h2 className="booking-card__header-heading">
|
|
355
|
+
{translations.OPTIONS_FORM.PER_UNIT_TITLE}
|
|
356
|
+
</h2>
|
|
357
|
+
</div>
|
|
358
|
+
<div className="booking-card__body">
|
|
359
|
+
<OptionUnitsCard
|
|
360
|
+
units={optionUnits}
|
|
361
|
+
onUnitsChange={handleOnUnitsChange}
|
|
362
|
+
/>
|
|
363
|
+
</div>
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
)}
|
|
367
|
+
|
|
368
|
+
{optionPax && !isEmpty(optionPax) && (
|
|
369
|
+
<div className="form__group">
|
|
370
|
+
<div className="booking-card">
|
|
371
|
+
<div className="booking-card__header">
|
|
372
|
+
<h2 className="booking-card__header-heading">
|
|
373
|
+
{translations.OPTIONS_FORM.PER_PAX_TITLE}
|
|
374
|
+
</h2>
|
|
375
|
+
</div>
|
|
376
|
+
<div className="booking-card__body">
|
|
377
|
+
<OptionPaxCard
|
|
378
|
+
pax={optionPax}
|
|
379
|
+
onPaxChange={handleOnPaxChange}
|
|
380
|
+
requestRoomsPax={requestRoomsPax}
|
|
381
|
+
/>
|
|
382
|
+
</div>
|
|
383
|
+
</div>
|
|
384
|
+
</div>
|
|
385
|
+
)}
|
|
386
|
+
|
|
387
|
+
{groups && !isEmpty(groups) && (
|
|
388
|
+
<div className="form__group">
|
|
389
|
+
<div className="booking-card">
|
|
390
|
+
<div className="booking-card__header">
|
|
391
|
+
<h2 className="booking-card__header-heading">
|
|
392
|
+
{translations.OPTIONS_FORM.PER_BOOKING_TITLE}
|
|
393
|
+
</h2>
|
|
394
|
+
</div>
|
|
395
|
+
<div className="booking-card__body">
|
|
396
|
+
<div className="booking-card__group booking-card__group--active">
|
|
397
|
+
{groups.map((group, i) => (
|
|
398
|
+
<OptionBookingGroup
|
|
399
|
+
key={`${group.name}_${i}`}
|
|
400
|
+
group={group}
|
|
401
|
+
firstClassName={"booking-card__group-body"}
|
|
402
|
+
secondClassName={"booking-card__group-heading"}
|
|
403
|
+
parentId={`booking_${group.name}`}
|
|
404
|
+
onGroupChange={handleOnGroupChange}
|
|
405
|
+
/>
|
|
406
|
+
))}
|
|
407
|
+
{airlineGroups?.map((group, i) => (
|
|
408
|
+
<OptionBookingAirlineGroup
|
|
409
|
+
key={`${group.label}_${i}`}
|
|
410
|
+
airGroup={group}
|
|
411
|
+
onGroupChange={handleOnAirlineGroupChange}
|
|
412
|
+
/>
|
|
413
|
+
))}
|
|
414
|
+
{airportGroups?.map((group, i) => (
|
|
415
|
+
<OptionBookingAirlineGroup
|
|
416
|
+
key={`${group.label}_${i}`}
|
|
417
|
+
airGroup={group}
|
|
418
|
+
onGroupChange={handleOnAirportGroupChange}
|
|
419
|
+
/>
|
|
420
|
+
))}
|
|
421
|
+
</div>
|
|
422
|
+
</div>
|
|
423
|
+
</div>
|
|
424
|
+
</div>
|
|
425
|
+
)}
|
|
426
|
+
|
|
427
|
+
{isEmpty(groups) && isEmpty(optionUnits) && isEmpty(optionPax) && (
|
|
428
|
+
<NoOptions />
|
|
429
|
+
)}
|
|
430
|
+
</div>
|
|
431
|
+
)}
|
|
432
|
+
<div className="booking__navigator">
|
|
433
|
+
{hasPrevious && (
|
|
434
|
+
<>
|
|
435
|
+
{settings.skipRouter ? (
|
|
436
|
+
<button
|
|
437
|
+
type="button"
|
|
438
|
+
title={translations.STEPS.PREVIOUS}
|
|
439
|
+
onClick={() => goPrevious()}
|
|
440
|
+
className="cta cta--secondary"
|
|
441
|
+
>
|
|
442
|
+
{translations.STEPS.PREVIOUS}
|
|
443
|
+
</button>
|
|
444
|
+
) : (
|
|
445
|
+
<Link
|
|
446
|
+
to={previousUrl}
|
|
447
|
+
title={translations.STEPS.PREVIOUS}
|
|
448
|
+
className="cta cta--secondary"
|
|
449
|
+
>
|
|
450
|
+
{translations.STEPS.PREVIOUS}
|
|
451
|
+
</Link>
|
|
452
|
+
)}
|
|
453
|
+
</>
|
|
454
|
+
)}
|
|
455
|
+
{token && settings.options.reportPrintActionId && (
|
|
456
|
+
<PrintOfferButton
|
|
457
|
+
bookingPackage={packageDetails}
|
|
458
|
+
getPax={getPax}
|
|
459
|
+
tagIds={tagIds}
|
|
460
|
+
printActionId={settings.options.reportPrintActionId}
|
|
461
|
+
labelIdle={translations.PRINT_OFFER_BUTTON.LABEL_IDLE}
|
|
462
|
+
labelCreating={translations.PRINT_OFFER_BUTTON.LABEL_CREATING}
|
|
463
|
+
labelPrinting={translations.PRINT_OFFER_BUTTON.LABEL_PRINTING}
|
|
464
|
+
className="cta spinner-button"
|
|
465
|
+
/>
|
|
466
|
+
)}
|
|
467
|
+
<button
|
|
468
|
+
type="submit"
|
|
469
|
+
title={translations.STEPS.NEXT}
|
|
470
|
+
disabled={isLoading}
|
|
471
|
+
className={buildClassName(["cta", isLoading && "cta--disabled"])}
|
|
472
|
+
>
|
|
473
|
+
{translations.STEPS.NEXT}
|
|
474
|
+
</button>
|
|
475
|
+
</div>
|
|
476
|
+
</form>
|
|
477
|
+
</>
|
|
478
|
+
);
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
export default OptionsForm;
|