@qite/tide-booking-component 1.3.4 → 1.3.6

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.
Files changed (41) hide show
  1. package/build/build-cjs/booking-wizard/features/booking/booking-slice.d.ts +2 -1
  2. package/build/build-cjs/booking-wizard/features/booking/selectors.d.ts +1 -0
  3. package/build/build-cjs/booking-wizard/features/sidebar/sidebar-util.d.ts +3 -3
  4. package/build/build-cjs/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +5 -5
  5. package/build/build-cjs/booking-wizard/types.d.ts +10 -1
  6. package/build/build-cjs/index.js +515 -293
  7. package/build/build-cjs/shared/utils/localization-util.d.ts +7 -0
  8. package/build/build-esm/booking-wizard/features/booking/booking-slice.d.ts +2 -1
  9. package/build/build-esm/booking-wizard/features/booking/selectors.d.ts +1 -0
  10. package/build/build-esm/booking-wizard/features/sidebar/sidebar-util.d.ts +3 -3
  11. package/build/build-esm/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +5 -5
  12. package/build/build-esm/booking-wizard/types.d.ts +10 -1
  13. package/build/build-esm/index.js +517 -295
  14. package/build/build-esm/shared/utils/localization-util.d.ts +7 -0
  15. package/package.json +75 -75
  16. package/src/booking-product/components/product.tsx +316 -314
  17. package/src/booking-product/components/rooms.tsx +19 -15
  18. package/src/booking-wizard/components/print-offer-button.tsx +63 -63
  19. package/src/booking-wizard/features/booking/booking-self-contained.tsx +393 -389
  20. package/src/booking-wizard/features/booking/booking-slice.ts +668 -663
  21. package/src/booking-wizard/features/booking/booking.tsx +365 -361
  22. package/src/booking-wizard/features/booking/selectors.ts +445 -441
  23. package/src/booking-wizard/features/confirmation/confirmation.tsx +103 -97
  24. package/src/booking-wizard/features/flight-options/flight-utils.ts +522 -522
  25. package/src/booking-wizard/features/product-options/options-form.tsx +481 -481
  26. package/src/booking-wizard/features/sidebar/sidebar-util.ts +177 -177
  27. package/src/booking-wizard/features/summary/summary-booking-option-pax.tsx +25 -25
  28. package/src/booking-wizard/features/summary/summary.tsx +707 -674
  29. package/src/booking-wizard/features/travelers-form/travelers-form-slice.ts +164 -164
  30. package/src/booking-wizard/features/travelers-form/travelers-form.tsx +888 -754
  31. package/src/booking-wizard/settings-context.ts +62 -62
  32. package/src/booking-wizard/types.ts +289 -279
  33. package/src/booking-wizard/use-offer-printer.ts +117 -117
  34. package/src/shared/translations/en-GB.json +244 -237
  35. package/src/shared/translations/fr-BE.json +244 -238
  36. package/src/shared/translations/nl-BE.json +244 -237
  37. package/src/shared/utils/tide-api-utils.ts +36 -36
  38. package/styles/booking-wizard-variables.scss +873 -873
  39. package/styles/components/_booking.scss +879 -879
  40. package/styles/components/_dropdown.scss +72 -72
  41. package/styles/components/_form.scss +1583 -1583
@@ -1,361 +1,365 @@
1
- import { navigate, Router, useLocation } from "@reach/router";
2
- import React, { useContext } from "react";
3
- import { useSelector } from "react-redux";
4
- import {
5
- getDateFromParams,
6
- getFlightsFromParams,
7
- getNumberFromParams,
8
- getNumbersFromParams,
9
- getRoomsFromParams,
10
- getStringFromParams,
11
- } from "../../../shared/utils/query-string-util";
12
- import {
13
- fetchPackage,
14
- setAccommodationViewId,
15
- setAgentAdressId,
16
- setBookingAttributes,
17
- setBookingNumber,
18
- setBookingOptions,
19
- setBookingType,
20
- setCalculateDeposit,
21
- setGeneratePaymentUrl,
22
- setIsRetry,
23
- setLanguageCode,
24
- setOfficeId,
25
- setProductAttributes,
26
- setSkipPayment,
27
- setTagIds,
28
- setTranslations,
29
- } from "./booking-slice";
30
-
31
- import { isNil } from "lodash";
32
- import { useEffect } from "react";
33
- import StepRoute from "../../components/step-route";
34
- import SettingsContext from "../../settings-context";
35
- import { useAppDispatch } from "../../store";
36
- import Confirmation from "../confirmation/confirmation";
37
- import Error from "../error/error";
38
- import FlightOptionsForm from "../flight-options";
39
- import OptionsForm from "../product-options/options-form";
40
- import RoomOptionsForm from "../room-options";
41
- import Sidebar from "../sidebar";
42
- import Summary from "../summary/summary";
43
- import TravelersForm from "../travelers-form/travelers-form";
44
- import {
45
- selectBookingAttributes,
46
- selectBookingNumber,
47
- selectBookingRooms,
48
- selectIsRetry,
49
- selectIsUnavailable,
50
- selectPackageDetails,
51
- selectProductAttributes,
52
- selectTranslations,
53
- } from "./selectors";
54
-
55
- interface BookingProps {
56
- productCode: string;
57
- productName: string;
58
- thumbnailUrl?: string;
59
- }
60
-
61
- const Booking: React.FC<BookingProps> = ({
62
- productCode,
63
- productName,
64
- thumbnailUrl,
65
- }) => {
66
- const {
67
- officeId,
68
- bookingOptions,
69
- basePath,
70
- roomOptions,
71
- flightOptions,
72
- options,
73
- travellers,
74
- summary,
75
- confirmation,
76
- error,
77
- showSidebarDeposit,
78
- includeFlights,
79
- loaderComponent,
80
- skipPaymentWithAgent,
81
- generatePaymentUrl,
82
- tagIds,
83
- agentAdressId,
84
- language,
85
- translationFiles,
86
- accommodationViewId,
87
- isOffer,
88
- } = useContext(SettingsContext);
89
-
90
- const dispatch = useAppDispatch();
91
- const location = useLocation();
92
-
93
- const productAttributes = useSelector(selectProductAttributes);
94
- const bookingAttributes = useSelector(selectBookingAttributes);
95
- const rooms = useSelector(selectBookingRooms);
96
- const bookingNumber = useSelector(selectBookingNumber);
97
- const isRetry = useSelector(selectIsRetry);
98
- const packageDetails = useSelector(selectPackageDetails);
99
- const isUnvailable = useSelector(selectIsUnavailable);
100
- const translations = useSelector(selectTranslations);
101
-
102
- useEffect(() => {
103
- dispatch(setSkipPayment(skipPaymentWithAgent ?? false));
104
- dispatch(setGeneratePaymentUrl(generatePaymentUrl ?? false));
105
- }, [skipPaymentWithAgent, generatePaymentUrl]);
106
-
107
- useEffect(() => {
108
- const params = new URLSearchParams(location.search);
109
- const startDate = getDateFromParams(params, "startDate");
110
- const endDate = getDateFromParams(params, "endDate");
111
- const catalog = getNumberFromParams(params, "catalog");
112
- const rooms = getRoomsFromParams(params, "rooms");
113
- const flight = getFlightsFromParams(params, "flight");
114
- const flightRouteId = getStringFromParams(params, "flightRouteId");
115
- const vendorConfigurationId = getNumberFromParams(
116
- params,
117
- "vendorConfigurationId"
118
- );
119
- const allotmentName = getStringFromParams(params, "allotmentName");
120
- const allotmentIds = getNumbersFromParams(params, "allotmentId");
121
- const tourCode = getStringFromParams(params, "tourCode");
122
- const bookingNumber = params.get("bookingNr") ?? undefined;
123
-
124
- if (typeof window !== "undefined") {
125
- window.scrollTo(0, 0);
126
- }
127
-
128
- if (!isNil(bookingNumber)) {
129
- dispatch(setBookingNumber(bookingNumber));
130
- navigate(
131
- `${basePath}${confirmation.pathSuffix}?bookingNr=${bookingNumber}`
132
- );
133
- }
134
-
135
- if (
136
- !isNil(startDate) &&
137
- !isNil(endDate) &&
138
- !isNil(catalog) &&
139
- !isNil(rooms)
140
- ) {
141
- dispatch(
142
- setBookingAttributes({
143
- startDate,
144
- endDate,
145
- catalog,
146
- rooms,
147
- flight,
148
- includeFlights,
149
- allotmentName,
150
- allotmentIds,
151
- tourCode,
152
- flightRouteId,
153
- vendorConfigurationId,
154
- })
155
- );
156
- } else {
157
- console.error(
158
- "Failure when setting booking attributes",
159
- startDate,
160
- endDate,
161
- catalog,
162
- rooms
163
- );
164
- }
165
- }, [location.search, setBookingAttributes, setBookingNumber, includeFlights]);
166
-
167
- useEffect(() => {
168
- if (
169
- !productAttributes ||
170
- !bookingAttributes ||
171
- !isNil(bookingNumber) ||
172
- !isRetry
173
- ) {
174
- return;
175
- }
176
-
177
- // Retried
178
- dispatch(setIsRetry(false));
179
-
180
- // Fetch data
181
- const promise = dispatch(fetchPackage());
182
- return () => {
183
- promise.abort();
184
- };
185
- }, [isRetry]);
186
-
187
- useEffect(() => {
188
- if (!isNil(productCode) && !isNil(productName)) {
189
- dispatch(
190
- setProductAttributes({
191
- productCode,
192
- productName,
193
- })
194
- );
195
- } else {
196
- console.error(
197
- "Failure when setting product attributes",
198
- productCode,
199
- productName
200
- );
201
- }
202
- }, [productCode, productName, setProductAttributes]);
203
-
204
- const getTranslations = async () => {
205
- const translations = translationFiles?.map((x) =>
206
- fetch(x.path)
207
- .then((y) => y.json())
208
- .then((z) => ({ language: x.language, value: z }))
209
- );
210
- return translations && (await Promise.all(translations));
211
- };
212
-
213
- useEffect(() => {
214
- const loadTranslations = async () => {
215
- const translations = await getTranslations();
216
- dispatch(setTranslations(translations)); // Now dispatch the resolved value
217
- };
218
-
219
- loadTranslations();
220
-
221
- dispatch(setOfficeId(officeId));
222
- dispatch(setLanguageCode(language));
223
- dispatch(setBookingOptions(bookingOptions));
224
- dispatch(setCalculateDeposit(showSidebarDeposit));
225
- if (tagIds && tagIds.length > 0) {
226
- dispatch(setTagIds(tagIds ?? undefined));
227
- }
228
- dispatch(setAgentAdressId(agentAdressId ?? undefined));
229
- if (agentAdressId && agentAdressId != 0) {
230
- dispatch(setBookingType("b2b"));
231
- }
232
- if (accommodationViewId && accommodationViewId != 0) {
233
- dispatch(setAccommodationViewId(accommodationViewId));
234
- }
235
- }, [
236
- officeId,
237
- language,
238
- bookingOptions,
239
- showSidebarDeposit,
240
- setOfficeId,
241
- setLanguageCode,
242
- setCalculateDeposit,
243
- tagIds,
244
- agentAdressId,
245
- accommodationViewId,
246
- ]);
247
-
248
- useEffect(() => {
249
- if (
250
- !productAttributes ||
251
- !bookingAttributes ||
252
- !rooms?.length ||
253
- !isNil(bookingNumber) ||
254
- !isNil(packageDetails)
255
- ) {
256
- return;
257
- }
258
- // Fetch data
259
- const promise = dispatch(fetchPackage());
260
- return () => {
261
- promise.abort();
262
- };
263
- }, [
264
- productAttributes,
265
- bookingAttributes,
266
- rooms,
267
- bookingNumber,
268
- packageDetails,
269
- ]);
270
-
271
- let numberIndex = 1;
272
-
273
- return (
274
- <>
275
- {((productAttributes && bookingAttributes && packageDetails) ||
276
- bookingNumber) && (
277
- <div className="booking">
278
- <div className="booking__content">
279
- <div className="booking__panel">
280
- <Router basepath={basePath}>
281
- {!flightOptions.isHidden && flightOptions.pathSuffix && (
282
- <StepRoute
283
- path={flightOptions.pathSuffix}
284
- number={numberIndex++}
285
- title={translations.STEPS.FLIGHT_OPTIONS}
286
- component={<FlightOptionsForm />}
287
- />
288
- )}
289
- {!roomOptions.isHidden && roomOptions.pathSuffix && (
290
- <StepRoute
291
- path={roomOptions.pathSuffix}
292
- number={numberIndex++}
293
- title={translations.STEPS.ROOM_OPTIONS}
294
- component={<RoomOptionsForm />}
295
- />
296
- )}
297
- <StepRoute
298
- path={options.pathSuffix}
299
- number={numberIndex++}
300
- title={translations.STEPS.EXTRA_OPTIONS}
301
- component={<OptionsForm />}
302
- />
303
- <StepRoute
304
- path={travellers.pathSuffix}
305
- number={numberIndex++}
306
- title={translations.STEPS.PERSONAL_DETAILS}
307
- component={<TravelersForm />}
308
- />
309
- <StepRoute
310
- path={summary.pathSuffix}
311
- number={numberIndex++}
312
- title={translations.STEPS.SUMMARY}
313
- component={<Summary />}
314
- />
315
- <StepRoute
316
- path={confirmation.pathSuffix}
317
- number={numberIndex++}
318
- title={translations.STEPS.CONFIRMATION}
319
- component={<Confirmation />}
320
- />
321
- <StepRoute
322
- path={error.pathSuffix}
323
- number={numberIndex++}
324
- title={translations.STEPS.ERROR}
325
- component={<Error />}
326
- />
327
- </Router>
328
- </div>
329
- <div className="backdrop" id="backdrop"></div>
330
- {packageDetails && (
331
- <Sidebar productName={productName} thumbnailUrl={thumbnailUrl} />
332
- )}
333
- </div>
334
- </div>
335
- )}
336
- {!packageDetails && !bookingNumber && !isUnvailable && (
337
- <div className="booking">
338
- <div className="booking__loader">
339
- {loaderComponent}
340
- <p className="booking__loader-text">
341
- {isOffer
342
- ? translations.MAIN.PREPARING_OFFER
343
- : translations.MAIN.PREPARING_BOOKING}
344
- </p>
345
- </div>
346
- </div>
347
- )}
348
- {isUnvailable && (
349
- <div className="booking">
350
- <div className="booking__loader">
351
- <p className="booking__loader-text">
352
- {translations.MAIN.PRODUCT_UNAVAILABLE}
353
- </p>
354
- </div>
355
- </div>
356
- )}
357
- </>
358
- );
359
- };
360
-
361
- export default Booking;
1
+ import { navigate, Router, useLocation } from "@reach/router";
2
+ import React, { useContext } from "react";
3
+ import { useSelector } from "react-redux";
4
+ import {
5
+ getDateFromParams,
6
+ getFlightsFromParams,
7
+ getNumberFromParams,
8
+ getNumbersFromParams,
9
+ getRoomsFromParams,
10
+ getStringFromParams,
11
+ } from "../../../shared/utils/query-string-util";
12
+ import {
13
+ fetchPackage,
14
+ setAccommodationViewId,
15
+ setAgentAdressId,
16
+ setBookingAttributes,
17
+ setBookingNumber,
18
+ setBookingOptions,
19
+ setBookingType,
20
+ setCalculateDeposit,
21
+ setGeneratePaymentUrl,
22
+ setIsRetry,
23
+ setLanguageCode,
24
+ setOfficeId,
25
+ setProductAttributes,
26
+ setSkipPayment,
27
+ setTagIds,
28
+ setTranslations,
29
+ } from "./booking-slice";
30
+
31
+ import { isNil } from "lodash";
32
+ import { useEffect } from "react";
33
+ import StepRoute from "../../components/step-route";
34
+ import SettingsContext from "../../settings-context";
35
+ import { useAppDispatch } from "../../store";
36
+ import Confirmation from "../confirmation/confirmation";
37
+ import Error from "../error/error";
38
+ import FlightOptionsForm from "../flight-options";
39
+ import OptionsForm from "../product-options/options-form";
40
+ import RoomOptionsForm from "../room-options";
41
+ import Sidebar from "../sidebar";
42
+ import Summary from "../summary/summary";
43
+ import TravelersForm from "../travelers-form/travelers-form";
44
+ import {
45
+ selectBookingAttributes,
46
+ selectBookingNumber,
47
+ selectBookingRooms,
48
+ selectIsRetry,
49
+ selectIsUnavailable,
50
+ selectPackageDetails,
51
+ selectProductAttributes,
52
+ selectTranslations,
53
+ } from "./selectors";
54
+
55
+ interface BookingProps {
56
+ productCode: string;
57
+ productName: string;
58
+ thumbnailUrl?: string;
59
+ }
60
+
61
+ const Booking: React.FC<BookingProps> = ({
62
+ productCode,
63
+ productName,
64
+ thumbnailUrl,
65
+ }) => {
66
+ const {
67
+ officeId,
68
+ bookingOptions,
69
+ basePath,
70
+ roomOptions,
71
+ flightOptions,
72
+ options,
73
+ travellers,
74
+ summary,
75
+ confirmation,
76
+ error,
77
+ showSidebarDeposit,
78
+ includeFlights,
79
+ loaderComponent,
80
+ skipPaymentWithAgent,
81
+ generatePaymentUrl,
82
+ tagIds,
83
+ agentAdressId,
84
+ language,
85
+ translationFiles,
86
+ accommodationViewId,
87
+ isOffer,
88
+ allowOption
89
+ } = useContext(SettingsContext);
90
+
91
+ const dispatch = useAppDispatch();
92
+ const location = useLocation();
93
+
94
+ const productAttributes = useSelector(selectProductAttributes);
95
+ const bookingAttributes = useSelector(selectBookingAttributes);
96
+ const rooms = useSelector(selectBookingRooms);
97
+ const bookingNumber = useSelector(selectBookingNumber);
98
+ const isRetry = useSelector(selectIsRetry);
99
+ const packageDetails = useSelector(selectPackageDetails);
100
+ const isUnvailable = useSelector(selectIsUnavailable);
101
+ const translations = useSelector(selectTranslations);
102
+
103
+ useEffect(() => {
104
+ dispatch(setSkipPayment(skipPaymentWithAgent ?? false));
105
+ dispatch(setGeneratePaymentUrl(generatePaymentUrl ?? false));
106
+ }, [skipPaymentWithAgent, generatePaymentUrl]);
107
+
108
+ useEffect(() => {
109
+ const params = new URLSearchParams(location.search);
110
+ const startDate = getDateFromParams(params, "startDate");
111
+ const endDate = getDateFromParams(params, "endDate");
112
+ const catalogueId = getNumberFromParams(params, "catalogueId")
113
+ ?? getNumberFromParams(params, "catalog");
114
+ const rooms = getRoomsFromParams(params, "rooms");
115
+ const flight = getFlightsFromParams(params, "flight");
116
+ const flightRouteId = getStringFromParams(params, "flightRouteId");
117
+ const vendorConfigurationId = getNumberFromParams(
118
+ params,
119
+ "vendorConfigurationId"
120
+ );
121
+ const allotmentName = getStringFromParams(params, "allotmentName");
122
+ const allotmentIds = getNumbersFromParams(params, "allotmentId");
123
+ const tourCode = getStringFromParams(params, "tourCode");
124
+ const bookingNumber = params.get("bookingNr") ?? undefined;
125
+
126
+ if (typeof window !== "undefined") {
127
+ window.scrollTo(0, 0);
128
+ }
129
+
130
+ if (!isNil(bookingNumber)) {
131
+ dispatch(setBookingNumber(bookingNumber));
132
+ navigate(
133
+ `${basePath}${confirmation.pathSuffix}?bookingNr=${bookingNumber}`
134
+ );
135
+ }
136
+
137
+ if (
138
+ !isNil(startDate) &&
139
+ !isNil(endDate) &&
140
+ !isNil(catalogueId) &&
141
+ !isNil(rooms)
142
+ ) {
143
+ dispatch(
144
+ setBookingAttributes({
145
+ startDate,
146
+ endDate,
147
+ catalogueId,
148
+ rooms,
149
+ flight,
150
+ includeFlights,
151
+ allotmentName,
152
+ allotmentIds,
153
+ tourCode,
154
+ flightRouteId,
155
+ vendorConfigurationId,
156
+ })
157
+ );
158
+ } else {
159
+ console.error(
160
+ "Failure when setting booking attributes",
161
+ startDate,
162
+ endDate,
163
+ catalogueId,
164
+ rooms
165
+ );
166
+ }
167
+ }, [location.search, setBookingAttributes, setBookingNumber, includeFlights]);
168
+
169
+ useEffect(() => {
170
+ if (
171
+ !productAttributes ||
172
+ !bookingAttributes ||
173
+ !isNil(bookingNumber) ||
174
+ !isRetry
175
+ ) {
176
+ return;
177
+ }
178
+
179
+ // Retried
180
+ dispatch(setIsRetry(false));
181
+
182
+ // Fetch data
183
+ const promise = dispatch(fetchPackage());
184
+ return () => {
185
+ promise.abort();
186
+ };
187
+ }, [isRetry]);
188
+
189
+ useEffect(() => {
190
+ if (!isNil(productCode) && !isNil(productName)) {
191
+ dispatch(
192
+ setProductAttributes({
193
+ productCode,
194
+ productName,
195
+ })
196
+ );
197
+ } else {
198
+ console.error(
199
+ "Failure when setting product attributes",
200
+ productCode,
201
+ productName
202
+ );
203
+ }
204
+ }, [productCode, productName, setProductAttributes]);
205
+
206
+ const getTranslations = async () => {
207
+ const translations = translationFiles?.map((x) =>
208
+ fetch(x.path)
209
+ .then((y) => y.json())
210
+ .then((z) => ({ language: x.language, value: z }))
211
+ );
212
+ return translations && (await Promise.all(translations));
213
+ };
214
+
215
+ useEffect(() => {
216
+ const loadTranslations = async () => {
217
+ const translations = await getTranslations();
218
+ dispatch(setTranslations(translations)); // Now dispatch the resolved value
219
+ };
220
+
221
+ loadTranslations();
222
+
223
+ dispatch(setOfficeId(officeId));
224
+ dispatch(setLanguageCode(language));
225
+ dispatch(setBookingOptions(bookingOptions));
226
+ dispatch(setCalculateDeposit(showSidebarDeposit));
227
+ if (tagIds && tagIds.length > 0) {
228
+ dispatch(setTagIds(tagIds ?? undefined));
229
+ }
230
+ dispatch(setAgentAdressId(agentAdressId ?? undefined));
231
+ if (agentAdressId && agentAdressId != 0) {
232
+ dispatch(setBookingType("b2b"));
233
+ }
234
+ if (accommodationViewId && accommodationViewId != 0) {
235
+ dispatch(setAccommodationViewId(accommodationViewId));
236
+ }
237
+ }, [
238
+ officeId,
239
+ language,
240
+ bookingOptions,
241
+ showSidebarDeposit,
242
+ setOfficeId,
243
+ setLanguageCode,
244
+ setCalculateDeposit,
245
+ tagIds,
246
+ agentAdressId,
247
+ accommodationViewId,
248
+ ]);
249
+
250
+ useEffect(() => {
251
+ if (
252
+ !productAttributes ||
253
+ !bookingAttributes ||
254
+ !rooms?.length ||
255
+ !isNil(bookingNumber) ||
256
+ !isNil(packageDetails)
257
+ ) {
258
+ return;
259
+ }
260
+ // Fetch data
261
+ const promise = dispatch(fetchPackage());
262
+ return () => {
263
+ promise.abort();
264
+ };
265
+ }, [
266
+ productAttributes,
267
+ bookingAttributes,
268
+ rooms,
269
+ bookingNumber,
270
+ packageDetails,
271
+ ]);
272
+
273
+ let numberIndex = 1;
274
+
275
+ return (
276
+ <>
277
+ {((productAttributes && bookingAttributes && packageDetails) ||
278
+ bookingNumber) && (
279
+ <div className="booking">
280
+ <div className="booking__content">
281
+ <div className="booking__panel">
282
+ <Router basepath={basePath}>
283
+ {!flightOptions.isHidden && flightOptions.pathSuffix && (
284
+ <StepRoute
285
+ path={flightOptions.pathSuffix}
286
+ number={numberIndex++}
287
+ title={translations.STEPS.FLIGHT_OPTIONS}
288
+ component={<FlightOptionsForm />}
289
+ />
290
+ )}
291
+ {!roomOptions.isHidden && roomOptions.pathSuffix && (
292
+ <StepRoute
293
+ path={roomOptions.pathSuffix}
294
+ number={numberIndex++}
295
+ title={translations.STEPS.ROOM_OPTIONS}
296
+ component={<RoomOptionsForm />}
297
+ />
298
+ )}
299
+ <StepRoute
300
+ path={options.pathSuffix}
301
+ number={numberIndex++}
302
+ title={translations.STEPS.EXTRA_OPTIONS}
303
+ component={<OptionsForm />}
304
+ />
305
+ <StepRoute
306
+ path={travellers.pathSuffix}
307
+ number={numberIndex++}
308
+ title={translations.STEPS.PERSONAL_DETAILS}
309
+ component={<TravelersForm />}
310
+ />
311
+ <StepRoute
312
+ path={summary.pathSuffix}
313
+ number={numberIndex++}
314
+ title={translations.STEPS.SUMMARY}
315
+ component={<Summary />}
316
+ />
317
+ <StepRoute
318
+ path={confirmation.pathSuffix}
319
+ number={numberIndex++}
320
+ title={translations.STEPS.CONFIRMATION}
321
+ component={<Confirmation />}
322
+ />
323
+ <StepRoute
324
+ path={error.pathSuffix}
325
+ number={numberIndex++}
326
+ title={translations.STEPS.ERROR}
327
+ component={<Error />}
328
+ />
329
+ </Router>
330
+ </div>
331
+ <div className="backdrop" id="backdrop"></div>
332
+ {packageDetails && (
333
+ <Sidebar productName={productName} thumbnailUrl={thumbnailUrl} />
334
+ )}
335
+ </div>
336
+ </div>
337
+ )}
338
+ {!packageDetails && !bookingNumber && !isUnvailable && (
339
+ <div className="booking">
340
+ <div className="booking__loader">
341
+ {loaderComponent}
342
+ <p className="booking__loader-text">
343
+ {allowOption
344
+ ? translations.MAIN.PREPARING_DOSSIER
345
+ : isOffer
346
+ ? translations.MAIN.PREPARING_OFFER
347
+ : translations.MAIN.PREPARING_BOOKING}
348
+ </p>
349
+ </div>
350
+ </div>
351
+ )}
352
+ {isUnvailable && (
353
+ <div className="booking">
354
+ <div className="booking__loader">
355
+ <p className="booking__loader-text">
356
+ {translations.MAIN.PRODUCT_UNAVAILABLE}
357
+ </p>
358
+ </div>
359
+ </div>
360
+ )}
361
+ </>
362
+ );
363
+ };
364
+
365
+ export default Booking;