@qite/tide-booking-component 1.1.2 → 1.2.0
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-product/components/multi-range-filter.d.ts +12 -0
- package/build/build-cjs/booking-wizard/features/booking/api.d.ts +4 -1
- package/build/build-cjs/booking-wizard/features/booking/booking-slice.d.ts +7 -3
- package/build/build-cjs/booking-wizard/features/booking/selectors.d.ts +23 -17
- package/build/build-cjs/booking-wizard/features/flight-options/flight-filter.d.ts +9 -0
- package/build/build-cjs/booking-wizard/features/flight-options/flight-option-flight.d.ts +8 -0
- package/build/build-cjs/booking-wizard/features/flight-options/flight-option-modal.d.ts +3 -0
- package/build/build-cjs/booking-wizard/features/flight-options/flight-option.d.ts +4 -9
- package/build/build-cjs/booking-wizard/features/flight-options/flight-utils.d.ts +6 -0
- package/build/build-cjs/booking-wizard/features/room-options/room-utils.d.ts +9 -0
- package/build/build-cjs/booking-wizard/features/room-options/room.d.ts +12 -0
- package/build/build-cjs/booking-wizard/features/room-options/traveler-rooms.d.ts +9 -0
- package/build/build-cjs/booking-wizard/types.d.ts +101 -0
- package/build/build-cjs/index.js +1563 -606
- package/build/build-cjs/shared/utils/localization-util.d.ts +30 -2
- package/build/build-esm/booking-product/components/multi-range-filter.d.ts +12 -0
- package/build/build-esm/booking-wizard/features/booking/api.d.ts +4 -1
- package/build/build-esm/booking-wizard/features/booking/booking-slice.d.ts +7 -3
- package/build/build-esm/booking-wizard/features/booking/selectors.d.ts +23 -17
- package/build/build-esm/booking-wizard/features/flight-options/flight-filter.d.ts +9 -0
- package/build/build-esm/booking-wizard/features/flight-options/flight-option-flight.d.ts +8 -0
- package/build/build-esm/booking-wizard/features/flight-options/flight-option-modal.d.ts +3 -0
- package/build/build-esm/booking-wizard/features/flight-options/flight-option.d.ts +4 -9
- package/build/build-esm/booking-wizard/features/flight-options/flight-utils.d.ts +6 -0
- package/build/build-esm/booking-wizard/features/room-options/room-utils.d.ts +9 -0
- package/build/build-esm/booking-wizard/features/room-options/room.d.ts +12 -0
- package/build/build-esm/booking-wizard/features/room-options/traveler-rooms.d.ts +9 -0
- package/build/build-esm/booking-wizard/types.d.ts +101 -0
- package/build/build-esm/index.js +1564 -607
- package/build/build-esm/shared/utils/localization-util.d.ts +30 -2
- package/package.json +3 -3
- package/rollup.config.js +23 -23
- package/src/booking-product/components/multi-range-filter.css +115 -0
- package/src/booking-product/components/multi-range-filter.tsx +114 -0
- package/src/booking-wizard/components/labeled-input.tsx +64 -64
- package/src/booking-wizard/components/labeled-select.tsx +69 -69
- package/src/booking-wizard/components/step-indicator.tsx +3 -3
- package/src/booking-wizard/features/booking/api.ts +12 -1
- package/src/booking-wizard/features/booking/booking-self-contained.tsx +51 -21
- package/src/booking-wizard/features/booking/booking-slice.ts +45 -9
- package/src/booking-wizard/features/booking/booking.tsx +68 -57
- package/src/booking-wizard/features/booking/selectors.ts +38 -11
- package/src/booking-wizard/features/flight-options/flight-filter.tsx +343 -0
- package/src/booking-wizard/features/flight-options/flight-option-flight.tsx +350 -0
- package/src/booking-wizard/features/flight-options/flight-option-modal.tsx +3 -23
- package/src/booking-wizard/features/flight-options/flight-option.tsx +30 -267
- package/src/booking-wizard/features/flight-options/flight-utils.ts +401 -0
- package/src/booking-wizard/features/flight-options/index.tsx +58 -95
- package/src/booking-wizard/features/price-details/util.ts +6 -6
- package/src/booking-wizard/features/product-options/option-room.tsx +3 -5
- package/src/booking-wizard/features/product-options/options-form.tsx +46 -54
- package/src/booking-wizard/features/room-options/index.tsx +48 -144
- package/src/booking-wizard/features/room-options/room-utils.ts +143 -0
- package/src/booking-wizard/features/room-options/room.tsx +124 -0
- package/src/booking-wizard/features/room-options/traveler-rooms.tsx +63 -0
- package/src/booking-wizard/features/sidebar/sidebar-util.ts +2 -2
- package/src/booking-wizard/features/summary/summary.tsx +2 -2
- package/src/booking-wizard/features/travelers-form/travelers-form.tsx +1 -1
- package/src/booking-wizard/types.ts +116 -0
- package/src/shared/components/rating.tsx +21 -21
- package/src/shared/translations/fr-BE.json +222 -192
- package/src/shared/translations/nl-BE.json +222 -192
- package/src/shared/utils/class-util.ts +9 -9
- package/tsconfig.json +24 -24
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
} from "../booking/booking-slice";
|
|
31
31
|
import { FLIGHT_OPTIONS_FORM_STEP, ROOM_OPTIONS_FORM_STEP, TRAVELERS_FORM_STEP } from "../booking/constants";
|
|
32
32
|
import {
|
|
33
|
+
selectAvailabilities,
|
|
33
34
|
selectBookingPackagePax,
|
|
34
35
|
selectBookingQueryString,
|
|
35
36
|
selectIsFetchingProductOptions,
|
|
@@ -46,6 +47,7 @@ import {
|
|
|
46
47
|
selectTranslations
|
|
47
48
|
} from "../booking/selectors";
|
|
48
49
|
import { fetchPriceDetails } from "../price-details/price-details-slice";
|
|
50
|
+
import { updatePackageRooms } from "../room-options/room-utils";
|
|
49
51
|
import NoOptions from "./no-options";
|
|
50
52
|
import OptionBookingAirlineGroup from "./option-booking-airline-group";
|
|
51
53
|
import OptionBookingGroup from "./option-booking-group";
|
|
@@ -71,12 +73,13 @@ const OptionsForm: React.FC<OptionsFormProps> = () => {
|
|
|
71
73
|
const airportGroups = useSelector(selectPackageAirportGroups);
|
|
72
74
|
const optionUnits = useSelector(selectPackageOptionUnits);
|
|
73
75
|
const optionPax = useSelector(selectPackageOptionPax);
|
|
74
|
-
|
|
76
|
+
const availabilities = useSelector(selectAvailabilities);
|
|
77
|
+
|
|
75
78
|
// ROOMS
|
|
76
79
|
const showRoomOptions = settings.roomOptions.isHidden;
|
|
77
80
|
const packageRooms = useSelector(selectPackageRooms);
|
|
78
81
|
const pax = useSelector(selectBookingPackagePax);
|
|
79
|
-
|
|
82
|
+
|
|
80
83
|
const getRoomPax = (index: number) => {
|
|
81
84
|
var room = requestRooms?.find((x) => x.index == index);
|
|
82
85
|
var bookingPackagePax = pax.filter((x) =>
|
|
@@ -84,7 +87,7 @@ const OptionsForm: React.FC<OptionsFormProps> = () => {
|
|
|
84
87
|
);
|
|
85
88
|
return bookingPackagePax.length > 0 ? bookingPackagePax : room?.pax ?? [];
|
|
86
89
|
};
|
|
87
|
-
|
|
90
|
+
|
|
88
91
|
const handleOnRoomChange = (
|
|
89
92
|
index: number,
|
|
90
93
|
accommodationCode: string,
|
|
@@ -92,21 +95,7 @@ const OptionsForm: React.FC<OptionsFormProps> = () => {
|
|
|
92
95
|
) => {
|
|
93
96
|
if (!packageRooms) return;
|
|
94
97
|
|
|
95
|
-
const updatedPackageRooms = packageRooms
|
|
96
|
-
if (room.index !== index) return room;
|
|
97
|
-
|
|
98
|
-
return {
|
|
99
|
-
...room,
|
|
100
|
-
options: room.options.map((option) => {
|
|
101
|
-
return {
|
|
102
|
-
...option,
|
|
103
|
-
isSelected:
|
|
104
|
-
option.accommodationCode === accommodationCode &&
|
|
105
|
-
option.regimeCode === regimeCode,
|
|
106
|
-
};
|
|
107
|
-
}),
|
|
108
|
-
};
|
|
109
|
-
});
|
|
98
|
+
const updatedPackageRooms = updatePackageRooms(packageRooms, index, accommodationCode, regimeCode, availabilities!);
|
|
110
99
|
|
|
111
100
|
dispatch(setPackageRooms(updatedPackageRooms));
|
|
112
101
|
dispatch(fetchPriceDetails());
|
|
@@ -234,17 +223,18 @@ const OptionsForm: React.FC<OptionsFormProps> = () => {
|
|
|
234
223
|
}, []);
|
|
235
224
|
|
|
236
225
|
const goPrevious = () => {
|
|
237
|
-
if (settings.
|
|
238
|
-
dispatch(setCurrentStep(ROOM_OPTIONS_FORM_STEP));
|
|
239
|
-
} else {
|
|
226
|
+
if (settings.roomOptions.isHidden) {
|
|
240
227
|
dispatch(setCurrentStep(FLIGHT_OPTIONS_FORM_STEP));
|
|
228
|
+
} else {
|
|
229
|
+
dispatch(setCurrentStep(ROOM_OPTIONS_FORM_STEP));
|
|
241
230
|
}
|
|
242
231
|
};
|
|
243
232
|
|
|
244
|
-
const previousUrl = settings.
|
|
245
|
-
? `${settings.basePath}${settings.
|
|
246
|
-
: `${settings.basePath}${settings.
|
|
233
|
+
const previousUrl = settings.roomOptions.isHidden
|
|
234
|
+
? `${settings.basePath}${settings.flightOptions.pathSuffix}?${bookingQueryString}`
|
|
235
|
+
: `${settings.basePath}${settings.roomOptions.pathSuffix}?${bookingQueryString}`;
|
|
247
236
|
const hasPrevious = !settings.roomOptions.isHidden || !settings.flightOptions.isHidden;
|
|
237
|
+
const showPackageTagsOrRoomoptions = showRoomOptions || (packageTags && !isEmpty(packageTags));
|
|
248
238
|
|
|
249
239
|
return (
|
|
250
240
|
<>
|
|
@@ -258,7 +248,7 @@ const OptionsForm: React.FC<OptionsFormProps> = () => {
|
|
|
258
248
|
{isLoading && settings.loaderComponent}
|
|
259
249
|
{!isLoading && (
|
|
260
250
|
<div className="form__region">
|
|
261
|
-
{
|
|
251
|
+
{showPackageTagsOrRoomoptions && (
|
|
262
252
|
<div className="form__group">
|
|
263
253
|
<div className="booking-card">
|
|
264
254
|
<div className="booking-card__body">
|
|
@@ -290,35 +280,37 @@ const OptionsForm: React.FC<OptionsFormProps> = () => {
|
|
|
290
280
|
</tbody>
|
|
291
281
|
</table>
|
|
292
282
|
)}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
<
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
283
|
+
{packageTags && !isEmpty(packageTags) && (
|
|
284
|
+
<div className="booking-card__tag-translations">
|
|
285
|
+
{packageTags.map((tag, index) => (
|
|
286
|
+
<label
|
|
287
|
+
key={index}
|
|
288
|
+
htmlFor={`tag-translation-${index}-${tag.title}`}
|
|
289
|
+
className="checkbox__label tag-translation"
|
|
290
|
+
>
|
|
291
|
+
<div className="tag-translation-input__container">
|
|
292
|
+
<input
|
|
293
|
+
type="checkbox"
|
|
294
|
+
id={`tag-translation-${index}-${tag.title}`}
|
|
295
|
+
name={`tag-translation-${index}-${tag.title}`}
|
|
296
|
+
className="checkbox__input"
|
|
297
|
+
checked={tagIds?.includes(tag.id)}
|
|
298
|
+
onChange={(e) =>
|
|
299
|
+
handleOnTagChange(tag.id, e.target.checked)
|
|
300
|
+
}
|
|
301
|
+
/>
|
|
302
|
+
</div>
|
|
303
|
+
<span className="tag-translation__title">
|
|
304
|
+
{tag.title}
|
|
305
|
+
</span>
|
|
306
|
+
|
|
307
|
+
<span className="tag-translation__description">
|
|
308
|
+
{tag.description}
|
|
309
|
+
</span>
|
|
310
|
+
</label>
|
|
311
|
+
))}
|
|
312
|
+
</div>
|
|
313
|
+
)}
|
|
322
314
|
</div>
|
|
323
315
|
</div>
|
|
324
316
|
</div>
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import React, { useContext, useEffect } from "react";
|
|
2
|
-
// import Heart from "react-heart";
|
|
3
|
-
|
|
4
1
|
import {
|
|
5
2
|
BookingPackageFlight
|
|
6
3
|
} from "@qite/tide-client/build/types";
|
|
7
|
-
import { navigate } from "@reach/router";
|
|
4
|
+
import { Link, navigate } from "@reach/router";
|
|
5
|
+
import React, { useContext, useEffect } from "react";
|
|
8
6
|
import { useSelector } from "react-redux";
|
|
9
7
|
import { buildClassName } from "../../../shared/utils/class-util";
|
|
10
8
|
import SettingsContext from "../../settings-context";
|
|
@@ -16,61 +14,47 @@ import {
|
|
|
16
14
|
} from "../booking/booking-slice";
|
|
17
15
|
import { FLIGHT_OPTIONS_FORM_STEP, OPTIONS_FORM_STEP } from "../booking/constants";
|
|
18
16
|
import {
|
|
19
|
-
|
|
17
|
+
selectAccommodationViews,
|
|
18
|
+
selectAvailabilities,
|
|
20
19
|
selectBookingQueryString,
|
|
21
20
|
selectIsFetchingProductOptions,
|
|
22
21
|
selectPackageDetails,
|
|
23
|
-
selectPackageOptionPax,
|
|
24
22
|
selectPackageRooms,
|
|
25
|
-
selectRequestRooms,
|
|
26
23
|
selectTranslations
|
|
27
24
|
} from "../booking/selectors";
|
|
28
25
|
import { fetchPriceDetails } from "../price-details/price-details-slice";
|
|
29
|
-
import
|
|
30
|
-
|
|
26
|
+
import { buildSelectableRooms, updatePackageRooms } from "./room-utils";
|
|
27
|
+
import TravelerRooms from "./traveler-rooms";
|
|
31
28
|
|
|
32
29
|
interface RoomOptionsFormProps { }
|
|
33
30
|
|
|
34
31
|
const RoomOptionsForm: React.FC<RoomOptionsFormProps> = () => {
|
|
35
|
-
const
|
|
36
|
-
basePath,
|
|
37
|
-
flightOptions,
|
|
38
|
-
options,
|
|
39
|
-
loaderComponent,
|
|
40
|
-
skipRouter
|
|
41
|
-
} = useContext(SettingsContext);
|
|
32
|
+
const settings = useContext(SettingsContext);
|
|
42
33
|
|
|
43
34
|
const translations = useSelector(selectTranslations);
|
|
44
35
|
const dispatch = useAppDispatch();
|
|
45
36
|
const packageDetails = useSelector(selectPackageDetails);
|
|
46
|
-
const requestRooms = useSelector(selectRequestRooms);
|
|
47
|
-
const pax = useSelector(selectBookingPackagePax);
|
|
48
37
|
const packageRooms = useSelector(selectPackageRooms);
|
|
38
|
+
const availabilities = useSelector(selectAvailabilities);
|
|
49
39
|
const bookingQueryString = useSelector(selectBookingQueryString);
|
|
40
|
+
const accommodationViews = useSelector(selectAccommodationViews);
|
|
50
41
|
const isLoading = useSelector(selectIsFetchingProductOptions);
|
|
51
|
-
const optionPax = useSelector(selectPackageOptionPax);
|
|
52
42
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
);
|
|
58
|
-
return bookingPackagePax.length > 0 ? bookingPackagePax : room?.pax ?? [];
|
|
43
|
+
const rooms = buildSelectableRooms(packageRooms!, settings.accommodations, settings.regimes, accommodationViews);
|
|
44
|
+
|
|
45
|
+
const goPrevious = () => {
|
|
46
|
+
dispatch(setCurrentStep(FLIGHT_OPTIONS_FORM_STEP));
|
|
59
47
|
};
|
|
60
48
|
|
|
61
49
|
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (e) => {
|
|
62
|
-
if (skipRouter) {
|
|
63
|
-
if (flightOptions.isHidden) {
|
|
50
|
+
if (settings.skipRouter) {
|
|
51
|
+
if (settings.flightOptions.isHidden) {
|
|
64
52
|
dispatch(setCurrentStep(OPTIONS_FORM_STEP));
|
|
65
53
|
} else {
|
|
66
54
|
dispatch(setCurrentStep(FLIGHT_OPTIONS_FORM_STEP));
|
|
67
55
|
}
|
|
68
56
|
} else {
|
|
69
|
-
|
|
70
|
-
navigate(`${basePath}${options.pathSuffix}?${bookingQueryString}`);
|
|
71
|
-
} else {
|
|
72
|
-
navigate(`${basePath}${flightOptions.pathSuffix}?${bookingQueryString}`);
|
|
73
|
-
}
|
|
57
|
+
navigate(`${settings.basePath}${settings.options.pathSuffix}?${bookingQueryString}`);
|
|
74
58
|
}
|
|
75
59
|
|
|
76
60
|
e.preventDefault();
|
|
@@ -83,21 +67,7 @@ const RoomOptionsForm: React.FC<RoomOptionsFormProps> = () => {
|
|
|
83
67
|
) => {
|
|
84
68
|
if (!packageRooms) return;
|
|
85
69
|
|
|
86
|
-
const updatedPackageRooms = packageRooms
|
|
87
|
-
if (room.index !== index) return room;
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
...room,
|
|
91
|
-
options: room.options.map((option) => {
|
|
92
|
-
return {
|
|
93
|
-
...option,
|
|
94
|
-
isSelected:
|
|
95
|
-
option.accommodationCode === accommodationCode &&
|
|
96
|
-
option.regimeCode === regimeCode,
|
|
97
|
-
};
|
|
98
|
-
}),
|
|
99
|
-
};
|
|
100
|
-
});
|
|
70
|
+
const updatedPackageRooms = updatePackageRooms(packageRooms, index, accommodationCode, regimeCode, availabilities!);
|
|
101
71
|
|
|
102
72
|
dispatch(setPackageRooms(updatedPackageRooms));
|
|
103
73
|
dispatch(fetchPriceDetails());
|
|
@@ -109,6 +79,7 @@ const RoomOptionsForm: React.FC<RoomOptionsFormProps> = () => {
|
|
|
109
79
|
|
|
110
80
|
const outwardFlight = params.get("outwardflight") ?? undefined;
|
|
111
81
|
const returnFlight = params.get("returnflight") ?? undefined;
|
|
82
|
+
|
|
112
83
|
if (outwardFlight && returnFlight) {
|
|
113
84
|
const desiredOutwardFlight = packageDetails.outwardFlights.find(
|
|
114
85
|
(x) => x.entryLineGuid == outwardFlight
|
|
@@ -116,6 +87,7 @@ const RoomOptionsForm: React.FC<RoomOptionsFormProps> = () => {
|
|
|
116
87
|
const desiredReturnFlight = packageDetails.returnFlights.find(
|
|
117
88
|
(x) => x.entryLineGuid == returnFlight
|
|
118
89
|
);
|
|
90
|
+
|
|
119
91
|
if (desiredOutwardFlight && desiredReturnFlight) {
|
|
120
92
|
dispatch(
|
|
121
93
|
setPackage({
|
|
@@ -146,8 +118,6 @@ const RoomOptionsForm: React.FC<RoomOptionsFormProps> = () => {
|
|
|
146
118
|
dispatch(fetchPriceDetails());
|
|
147
119
|
}, []);
|
|
148
120
|
|
|
149
|
-
// const [active, setActive] = useState(false)
|
|
150
|
-
|
|
151
121
|
return (
|
|
152
122
|
<>
|
|
153
123
|
<form
|
|
@@ -158,103 +128,37 @@ const RoomOptionsForm: React.FC<RoomOptionsFormProps> = () => {
|
|
|
158
128
|
onSubmit={handleSubmit}
|
|
159
129
|
>
|
|
160
130
|
<div className="form__wrapper">
|
|
161
|
-
{
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
className={buildClassName([
|
|
169
|
-
"booking-card__group",
|
|
170
|
-
"booking-card__group--package",
|
|
171
|
-
])}
|
|
172
|
-
>
|
|
173
|
-
<span className="booking-card__tag">
|
|
174
|
-
{translations.OPTIONS_FORM.PACKAGE}
|
|
175
|
-
</span>
|
|
176
|
-
<div className="booking-card__group-body">
|
|
177
|
-
<table className="table table--striped">
|
|
178
|
-
<tbody>
|
|
179
|
-
{packageRooms &&
|
|
180
|
-
packageRooms.map((room) => (
|
|
181
|
-
<OptionRoom
|
|
182
|
-
key={room.index}
|
|
183
|
-
packageRoom={room}
|
|
184
|
-
pax={getRoomPax(room.index)}
|
|
185
|
-
optionPax={optionPax}
|
|
186
|
-
onRoomChange={handleOnRoomChange}
|
|
187
|
-
/>
|
|
188
|
-
))}
|
|
189
|
-
</tbody>
|
|
190
|
-
</table>
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
</div>
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
</div>
|
|
197
|
-
|
|
198
|
-
)} */}
|
|
199
|
-
|
|
200
|
-
<div className="form__room">
|
|
201
|
-
<div className="form__room__wrapper">
|
|
202
|
-
<div className="form__room__image">
|
|
203
|
-
<img src="https://media.istockphoto.com/id/1050564510/photo/3d-rendering-beautiful-luxury-bedroom-suite-in-hotel-with-tv.jpg?s=612x612&w=0&k=20&c=ZYEso7dgPl889aYddhY2Fj3GOyuwqliHkbbT8pjl_iM=" alt="" className="form__room__img"/>
|
|
204
|
-
</div>
|
|
205
|
-
<div className="form__room__body">
|
|
206
|
-
<div className="">
|
|
207
|
-
<h3 className="form__room__title">Tara Penthouse suite frontal seaview</h3>
|
|
208
|
-
<p> Carrer de Nicaragua, 146, Les Corts, 08029 Barcelona, Spanje – <a href="#">Toon kaart</a></p>
|
|
209
|
-
<ul className="list--usps form__room__usps">
|
|
210
|
-
<li className="list__item">1 tweepersoonsbed</li>
|
|
211
|
-
<li className="list__item">Max. 2 personen</li>
|
|
212
|
-
<li className="list__item">Gratis WiFi</li>
|
|
213
|
-
<li className="list__item">Airconditioning</li>
|
|
214
|
-
<li className="list__item">Eigen badkamer</li>
|
|
215
|
-
</ul>
|
|
216
|
-
<div className="form__room__select">
|
|
217
|
-
{/* <div className="select-wrapper">
|
|
218
|
-
<div className="select-wrapper__select">
|
|
219
|
-
<select>
|
|
220
|
-
<option value="STD">Standaard (gedeeltelijk tuinzicht - Bucuti WIng) </option>
|
|
221
|
-
<option value="SUP">Superior (tuinzicht - Bucuti WIng) (+ € 252,00)</option>
|
|
222
|
-
<option value="BUNG">Bungalow suite tuinzicht (+ € 858,38)</option>
|
|
223
|
-
<option value="DLX">Deluxe ocean (Bucuti Wing) (+ € 858,38)</option>
|
|
224
|
-
<option value="TAS">Tara Suite frontaal zeezicht (+ € 1.740,38)</option>
|
|
225
|
-
<option value="JRS">Junior Suite Zeezicht (Bucuti Wing) (+ € 1.740,38)</option>
|
|
226
|
-
<option value="BUNGO">Bungalow zeezicht (+ € 1.740,38)</option>
|
|
227
|
-
<option value="TAPS">Tara Penthouse suite frontaal zeezicht (+ € 3.276,00)</option>
|
|
228
|
-
</select>
|
|
229
|
-
</div>
|
|
230
|
-
</div> */}
|
|
231
|
-
<div className="select-wrapper">
|
|
232
|
-
<div className="select-wrapper__select">
|
|
233
|
-
<select>
|
|
234
|
-
<option value="KO">Kamer & Ontbijt </option>
|
|
235
|
-
<option value="LU">Lunch (+ € 354,38)</option>
|
|
236
|
-
<option value="HB">Half Pension (+ € 740,25)</option>
|
|
237
|
-
<option value="FB">Vol Pension (+ € 1.094,63)</option>
|
|
238
|
-
</select>
|
|
239
|
-
</div>
|
|
240
|
-
</div>
|
|
241
|
-
</div>
|
|
242
|
-
</div>
|
|
243
|
-
</div>
|
|
244
|
-
</div>
|
|
245
|
-
<div className="form__room__footer">
|
|
246
|
-
<div className="form__room__footer__top">
|
|
247
|
-
<p className="form__room__dates">01/11 - 08/11</p>
|
|
248
|
-
<span className="form__room__days">8 dagen, 7nachten</span>
|
|
249
|
-
</div>
|
|
250
|
-
<div className="form__room__footer__bottom">
|
|
251
|
-
<p className="form__room__price form__room__price--increase">+ <span>€ 216,00</span></p>
|
|
252
|
-
<button className="cta cta--secondary">Selecteer</button>
|
|
253
|
-
</div>
|
|
254
|
-
</div>
|
|
255
|
-
</div>
|
|
131
|
+
{rooms.map(room => (
|
|
132
|
+
<TravelerRooms
|
|
133
|
+
key={room.index}
|
|
134
|
+
index={room.index}
|
|
135
|
+
room={room}
|
|
136
|
+
onRoomChange={handleOnRoomChange} />
|
|
137
|
+
))}
|
|
256
138
|
</div>
|
|
257
139
|
<div className="booking__navigator">
|
|
140
|
+
{!settings.flightOptions.isHidden && (
|
|
141
|
+
<>
|
|
142
|
+
{settings.skipRouter ? (
|
|
143
|
+
<button
|
|
144
|
+
type="button"
|
|
145
|
+
title={translations.STEPS.PREVIOUS}
|
|
146
|
+
onClick={() => goPrevious()}
|
|
147
|
+
className="cta cta--secondary"
|
|
148
|
+
>
|
|
149
|
+
{translations.STEPS.PREVIOUS}
|
|
150
|
+
</button>
|
|
151
|
+
) : (
|
|
152
|
+
<Link
|
|
153
|
+
to={`${settings.basePath}${settings.flightOptions.pathSuffix}?${bookingQueryString}`}
|
|
154
|
+
title={translations.STEPS.PREVIOUS}
|
|
155
|
+
className="cta cta--secondary"
|
|
156
|
+
>
|
|
157
|
+
{translations.STEPS.PREVIOUS}
|
|
158
|
+
</Link>
|
|
159
|
+
)}
|
|
160
|
+
</>
|
|
161
|
+
)}
|
|
258
162
|
<button
|
|
259
163
|
type="submit"
|
|
260
164
|
title={translations.STEPS.NEXT}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { BookingPackageAvailability, BookingPackageRoom } from "@qite/tide-client/build/types";
|
|
2
|
+
import { AccommodationContent, RegimeContent, SelectableRoom, SelectableRoomAccommodation } from "../../types";
|
|
3
|
+
|
|
4
|
+
export const buildSelectableRooms = (
|
|
5
|
+
packageRooms: BookingPackageRoom[],
|
|
6
|
+
accommodations: AccommodationContent[] | undefined,
|
|
7
|
+
regimes: RegimeContent[] | undefined,
|
|
8
|
+
accommodationViews: { [key: string]: string } | undefined
|
|
9
|
+
) => {
|
|
10
|
+
return packageRooms.map(x => {
|
|
11
|
+
const selectedOption = x.options.find(x => x.isSelected)!;
|
|
12
|
+
const alternativeOptions = x.options
|
|
13
|
+
.filter(x => x.accommodationCode !== selectedOption.accommodationCode && !x.isLocked)
|
|
14
|
+
.sort((a, b) => a.price - b.price);
|
|
15
|
+
|
|
16
|
+
const alternativeAccommodations: SelectableRoomAccommodation[] = [];
|
|
17
|
+
alternativeOptions.forEach(x => {
|
|
18
|
+
const alternativeAccommodation = alternativeAccommodations.find(y => y.code === x.accommodationCode);
|
|
19
|
+
|
|
20
|
+
if (alternativeAccommodation) {
|
|
21
|
+
const regime = regimes?.find(y => y.code === x.regimeCode);
|
|
22
|
+
|
|
23
|
+
alternativeAccommodation.regimes.push({
|
|
24
|
+
code: x.regimeCode,
|
|
25
|
+
title: regime?.title ?? x.regimeName,
|
|
26
|
+
price: x.price
|
|
27
|
+
});
|
|
28
|
+
} else {
|
|
29
|
+
const accommodation = accommodations?.find(y => y.code === x.accommodationCode);
|
|
30
|
+
const regime = regimes?.find(y => y.code === x.regimeCode);
|
|
31
|
+
|
|
32
|
+
alternativeAccommodations.push({
|
|
33
|
+
code: x.accommodationCode,
|
|
34
|
+
regimeCode: x.regimeCode,
|
|
35
|
+
from: x.from,
|
|
36
|
+
to: x.to,
|
|
37
|
+
price: x.price,
|
|
38
|
+
regimes: [{
|
|
39
|
+
code: x.regimeCode,
|
|
40
|
+
title: regime?.title ?? x.regimeName,
|
|
41
|
+
price: x.price
|
|
42
|
+
}],
|
|
43
|
+
title: accommodation?.title ?? x.accommodationName,
|
|
44
|
+
image: accommodation?.imageUrl,
|
|
45
|
+
usps: accommodation?.usps ?? [],
|
|
46
|
+
description: accommodation?.description,
|
|
47
|
+
viewHtml: accommodationViews?.[x.accommodationCode]
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const accommodation = accommodations?.find(y => y.code === selectedOption.accommodationCode);
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
index: x.index,
|
|
56
|
+
selected: {
|
|
57
|
+
code: selectedOption.accommodationCode,
|
|
58
|
+
regimeCode: selectedOption.regimeCode,
|
|
59
|
+
price: selectedOption.price,
|
|
60
|
+
from: selectedOption.from,
|
|
61
|
+
to: selectedOption.to,
|
|
62
|
+
regimes: x.options
|
|
63
|
+
.filter(x => x.accommodationCode === selectedOption.accommodationCode)
|
|
64
|
+
.sort((a, b) => a.price - b.price)
|
|
65
|
+
.map(o => {
|
|
66
|
+
const regime = regimes?.find(y => y.code === o.regimeCode);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
code: o.regimeCode,
|
|
70
|
+
title: regime?.title ?? o.regimeName,
|
|
71
|
+
price: o.price
|
|
72
|
+
}
|
|
73
|
+
}),
|
|
74
|
+
title: accommodation?.title ?? selectedOption.accommodationName,
|
|
75
|
+
image: accommodation?.imageUrl,
|
|
76
|
+
usps: accommodation?.usps ?? [],
|
|
77
|
+
description: accommodation?.description,
|
|
78
|
+
viewHtml: accommodationViews?.[selectedOption.accommodationCode]
|
|
79
|
+
},
|
|
80
|
+
showAlternatives: false,
|
|
81
|
+
alternatives: alternativeAccommodations
|
|
82
|
+
} as SelectableRoom;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const updatePackageRooms = (rooms: BookingPackageRoom[], index: number, accommodationCode: string, regimeCode: string | null, availabilities: BookingPackageAvailability[]) => {
|
|
87
|
+
const updatedRooms = rooms.map((room) => {
|
|
88
|
+
if (room.index !== index) return room;
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
...room,
|
|
92
|
+
options: room.options.map((option) => {
|
|
93
|
+
return {
|
|
94
|
+
...option,
|
|
95
|
+
isSelected:
|
|
96
|
+
option.accommodationCode === accommodationCode &&
|
|
97
|
+
(option.regimeCode === regimeCode || (option.regimeCode === null && regimeCode === '')),
|
|
98
|
+
};
|
|
99
|
+
}),
|
|
100
|
+
};
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const selectedAccommodations = new Map<string, number>();
|
|
104
|
+
updatedRooms.map(x => x.options.find(x => x.isSelected)!).forEach(x => {
|
|
105
|
+
if (selectedAccommodations.has(x.accommodationCode)) {
|
|
106
|
+
selectedAccommodations.set(x.accommodationCode, selectedAccommodations.get(x.accommodationCode)! + 1);
|
|
107
|
+
} else {
|
|
108
|
+
selectedAccommodations.set(x.accommodationCode, 1);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const accoCounter = availabilities.map(x => ({ code: x.code, count: x.count }));
|
|
113
|
+
return updatedRooms.map(room => {
|
|
114
|
+
const selectedOption = room.options.find(x => x.isSelected)!;
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
...room,
|
|
118
|
+
options: room.options.map(option => {
|
|
119
|
+
const isCurrentOption = selectedOption.accommodationCode === option.accommodationCode;
|
|
120
|
+
const usedCount = selectedAccommodations.get(option.accommodationCode) ?? 0;
|
|
121
|
+
const availability = availabilities.find(x => x.code === option.accommodationCode);
|
|
122
|
+
|
|
123
|
+
if (availability) {
|
|
124
|
+
const accoCount = accoCounter.find(x => x.code === option.accommodationCode)!;
|
|
125
|
+
|
|
126
|
+
const roomsLeft = availability.count - usedCount;
|
|
127
|
+
let isOnRequest = isCurrentOption
|
|
128
|
+
? accoCount.count < 0 && (availability?.onRequestPossible ?? false)
|
|
129
|
+
: roomsLeft < 0 && (availability?.onRequestPossible ?? false);
|
|
130
|
+
if (isCurrentOption) accoCount.count--;
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
...option,
|
|
134
|
+
isLocked: !option.isSelected && !isOnRequest && roomsLeft < 0 && !availability.isExternal,
|
|
135
|
+
isOnRequest: isOnRequest
|
|
136
|
+
};
|
|
137
|
+
} else {
|
|
138
|
+
return option;
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|