@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.
Files changed (64) hide show
  1. package/build/build-cjs/booking-product/components/multi-range-filter.d.ts +12 -0
  2. package/build/build-cjs/booking-wizard/features/booking/api.d.ts +4 -1
  3. package/build/build-cjs/booking-wizard/features/booking/booking-slice.d.ts +7 -3
  4. package/build/build-cjs/booking-wizard/features/booking/selectors.d.ts +23 -17
  5. package/build/build-cjs/booking-wizard/features/flight-options/flight-filter.d.ts +9 -0
  6. package/build/build-cjs/booking-wizard/features/flight-options/flight-option-flight.d.ts +8 -0
  7. package/build/build-cjs/booking-wizard/features/flight-options/flight-option-modal.d.ts +3 -0
  8. package/build/build-cjs/booking-wizard/features/flight-options/flight-option.d.ts +4 -9
  9. package/build/build-cjs/booking-wizard/features/flight-options/flight-utils.d.ts +6 -0
  10. package/build/build-cjs/booking-wizard/features/room-options/room-utils.d.ts +9 -0
  11. package/build/build-cjs/booking-wizard/features/room-options/room.d.ts +12 -0
  12. package/build/build-cjs/booking-wizard/features/room-options/traveler-rooms.d.ts +9 -0
  13. package/build/build-cjs/booking-wizard/types.d.ts +101 -0
  14. package/build/build-cjs/index.js +1563 -606
  15. package/build/build-cjs/shared/utils/localization-util.d.ts +30 -2
  16. package/build/build-esm/booking-product/components/multi-range-filter.d.ts +12 -0
  17. package/build/build-esm/booking-wizard/features/booking/api.d.ts +4 -1
  18. package/build/build-esm/booking-wizard/features/booking/booking-slice.d.ts +7 -3
  19. package/build/build-esm/booking-wizard/features/booking/selectors.d.ts +23 -17
  20. package/build/build-esm/booking-wizard/features/flight-options/flight-filter.d.ts +9 -0
  21. package/build/build-esm/booking-wizard/features/flight-options/flight-option-flight.d.ts +8 -0
  22. package/build/build-esm/booking-wizard/features/flight-options/flight-option-modal.d.ts +3 -0
  23. package/build/build-esm/booking-wizard/features/flight-options/flight-option.d.ts +4 -9
  24. package/build/build-esm/booking-wizard/features/flight-options/flight-utils.d.ts +6 -0
  25. package/build/build-esm/booking-wizard/features/room-options/room-utils.d.ts +9 -0
  26. package/build/build-esm/booking-wizard/features/room-options/room.d.ts +12 -0
  27. package/build/build-esm/booking-wizard/features/room-options/traveler-rooms.d.ts +9 -0
  28. package/build/build-esm/booking-wizard/types.d.ts +101 -0
  29. package/build/build-esm/index.js +1564 -607
  30. package/build/build-esm/shared/utils/localization-util.d.ts +30 -2
  31. package/package.json +3 -3
  32. package/rollup.config.js +23 -23
  33. package/src/booking-product/components/multi-range-filter.css +115 -0
  34. package/src/booking-product/components/multi-range-filter.tsx +114 -0
  35. package/src/booking-wizard/components/labeled-input.tsx +64 -64
  36. package/src/booking-wizard/components/labeled-select.tsx +69 -69
  37. package/src/booking-wizard/components/step-indicator.tsx +3 -3
  38. package/src/booking-wizard/features/booking/api.ts +12 -1
  39. package/src/booking-wizard/features/booking/booking-self-contained.tsx +51 -21
  40. package/src/booking-wizard/features/booking/booking-slice.ts +45 -9
  41. package/src/booking-wizard/features/booking/booking.tsx +68 -57
  42. package/src/booking-wizard/features/booking/selectors.ts +38 -11
  43. package/src/booking-wizard/features/flight-options/flight-filter.tsx +343 -0
  44. package/src/booking-wizard/features/flight-options/flight-option-flight.tsx +350 -0
  45. package/src/booking-wizard/features/flight-options/flight-option-modal.tsx +3 -23
  46. package/src/booking-wizard/features/flight-options/flight-option.tsx +30 -267
  47. package/src/booking-wizard/features/flight-options/flight-utils.ts +401 -0
  48. package/src/booking-wizard/features/flight-options/index.tsx +58 -95
  49. package/src/booking-wizard/features/price-details/util.ts +6 -6
  50. package/src/booking-wizard/features/product-options/option-room.tsx +3 -5
  51. package/src/booking-wizard/features/product-options/options-form.tsx +46 -54
  52. package/src/booking-wizard/features/room-options/index.tsx +48 -144
  53. package/src/booking-wizard/features/room-options/room-utils.ts +143 -0
  54. package/src/booking-wizard/features/room-options/room.tsx +124 -0
  55. package/src/booking-wizard/features/room-options/traveler-rooms.tsx +63 -0
  56. package/src/booking-wizard/features/sidebar/sidebar-util.ts +2 -2
  57. package/src/booking-wizard/features/summary/summary.tsx +2 -2
  58. package/src/booking-wizard/features/travelers-form/travelers-form.tsx +1 -1
  59. package/src/booking-wizard/types.ts +116 -0
  60. package/src/shared/components/rating.tsx +21 -21
  61. package/src/shared/translations/fr-BE.json +222 -192
  62. package/src/shared/translations/nl-BE.json +222 -192
  63. package/src/shared/utils/class-util.ts +9 -9
  64. 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.map((room) => {
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.flightOptions.isHidden) {
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.flightOptions.isHidden
245
- ? `${settings.basePath}${settings.roomOptions.pathSuffix}?${bookingQueryString}`
246
- : `${settings.basePath}${settings.flightOptions.pathSuffix}?${bookingQueryString}`;
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
- {packageTags && (
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
- <div className="booking-card__tag-translations">
294
- {packageTags.map((tag, index) => (
295
- <label
296
- key={index}
297
- htmlFor={`tag-translation-${index}-${tag.title}`}
298
- className="checkbox__label tag-translation"
299
- >
300
- <div className="tag-translation-input__container">
301
- <input
302
- type="checkbox"
303
- id={`tag-translation-${index}-${tag.title}`}
304
- name={`tag-translation-${index}-${tag.title}`}
305
- className="checkbox__input"
306
- checked={tagIds?.includes(tag.id)}
307
- onChange={(e) =>
308
- handleOnTagChange(tag.id, e.target.checked)
309
- }
310
- />
311
- </div>
312
- <span className="tag-translation__title">
313
- {tag.title}
314
- </span>
315
- &nbsp;
316
- <span className="tag-translation__description">
317
- {tag.description}
318
- </span>
319
- </label>
320
- ))}
321
- </div>
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
+ &nbsp;
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
- selectBookingPackagePax,
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 OptionRoom from "../product-options/option-room";
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 getRoomPax = (index: number) => {
54
- var room = requestRooms?.find((x) => x.index == index);
55
- var bookingPackagePax = pax.filter((x) =>
56
- room?.pax.some((y) => y.id == x.id)
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
- if (flightOptions.isHidden) {
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.map((room) => {
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
- {/* {isLoading && loaderComponent}
162
- {!isLoading && (
163
- <div className="form__region">
164
- <div className="form__group">
165
- <div className="booking-card">
166
- <div className="booking-card__body">
167
- <div
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) (+ €&nbsp;252,00)</option>
222
- <option value="BUNG">Bungalow suite tuinzicht (+ €&nbsp;858,38)</option>
223
- <option value="DLX">Deluxe ocean (Bucuti Wing) (+ €&nbsp;858,38)</option>
224
- <option value="TAS">Tara Suite frontaal zeezicht (+ €&nbsp;1.740,38)</option>
225
- <option value="JRS">Junior Suite Zeezicht (Bucuti Wing) (+ €&nbsp;1.740,38)</option>
226
- <option value="BUNGO">Bungalow zeezicht (+ €&nbsp;1.740,38)</option>
227
- <option value="TAPS">Tara Penthouse suite frontaal zeezicht (+ €&nbsp;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 &amp; Ontbijt </option>
235
- <option value="LU">Lunch (+ €&nbsp;354,38)</option>
236
- <option value="HB">Half Pension (+ €&nbsp;740,25)</option>
237
- <option value="FB">Vol Pension (+ €&nbsp;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
+ }