@qite/tide-booking-component 0.0.2-preview.8 → 1.0.0-preview

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 (177) hide show
  1. package/README.md +1 -0
  2. package/build/build-cjs/booking-wizard/components/icon.d.ts +7 -7
  3. package/build/build-cjs/booking-wizard/components/labeled-input.d.ts +18 -18
  4. package/build/build-cjs/booking-wizard/components/labeled-select.d.ts +21 -21
  5. package/build/build-cjs/booking-wizard/components/message.d.ts +9 -8
  6. package/build/build-cjs/booking-wizard/components/product-card.d.ts +8 -9
  7. package/build/build-cjs/booking-wizard/components/rating.d.ts +6 -6
  8. package/build/build-cjs/booking-wizard/components/step-indicator.d.ts +6 -6
  9. package/build/build-cjs/booking-wizard/components/step-route.d.ts +9 -9
  10. package/build/build-cjs/booking-wizard/features/booking/api.d.ts +21 -0
  11. package/build/build-cjs/booking-wizard/features/booking/booking-slice.d.ts +124 -18
  12. package/build/build-cjs/booking-wizard/features/booking/booking.d.ts +8 -9
  13. package/build/build-cjs/booking-wizard/features/booking/selectors.d.ts +208 -0
  14. package/build/build-cjs/booking-wizard/features/confirmation/confirmation.d.ts +4 -5
  15. package/build/build-cjs/booking-wizard/features/error/error.d.ts +4 -5
  16. package/build/build-cjs/booking-wizard/features/price-details/price-details-api.d.ts +12 -6
  17. package/build/build-cjs/booking-wizard/features/price-details/price-details-slice.d.ts +105 -10
  18. package/build/build-cjs/booking-wizard/features/price-details/util.d.ts +5 -0
  19. package/build/build-cjs/booking-wizard/features/product-options/no-options.d.ts +2 -0
  20. package/build/build-cjs/booking-wizard/features/product-options/none-option.d.ts +17 -0
  21. package/build/build-cjs/booking-wizard/features/product-options/option-booking-group.d.ts +18 -0
  22. package/build/build-cjs/booking-wizard/features/product-options/option-item.d.ts +11 -0
  23. package/build/build-cjs/booking-wizard/features/product-options/option-pax-card.d.ts +9 -0
  24. package/build/build-cjs/booking-wizard/features/product-options/option-pax-group.d.ts +20 -0
  25. package/build/build-cjs/booking-wizard/features/product-options/option-room.d.ts +16 -0
  26. package/build/build-cjs/booking-wizard/features/product-options/option-unit-group.d.ts +20 -0
  27. package/build/build-cjs/booking-wizard/features/product-options/option-units-card.d.ts +9 -0
  28. package/build/build-cjs/booking-wizard/features/product-options/options-form.d.ts +4 -5
  29. package/build/build-cjs/booking-wizard/features/product-options/validate-form.d.ts +2 -2
  30. package/build/build-cjs/booking-wizard/features/sidebar/index.d.ts +7 -3
  31. package/build/build-cjs/booking-wizard/features/sidebar/sidebar-flight.d.ts +8 -0
  32. package/build/build-cjs/booking-wizard/features/sidebar/sidebar-util.d.ts +28 -4
  33. package/build/build-cjs/booking-wizard/features/sidebar/sidebar.d.ts +29 -21
  34. package/build/build-cjs/booking-wizard/features/summary/summary-booking-option-pax.d.ts +7 -0
  35. package/build/build-cjs/booking-wizard/features/summary/summary-booking-option-unit.d.ts +7 -0
  36. package/build/build-cjs/booking-wizard/features/summary/summary-flight.d.ts +8 -0
  37. package/build/build-cjs/booking-wizard/features/summary/summary-per-booking-option-group.d.ts +10 -0
  38. package/build/build-cjs/booking-wizard/features/summary/summary-per-pax-option-group.d.ts +10 -0
  39. package/build/build-cjs/booking-wizard/features/summary/summary-per-unit-option-group.d.ts +10 -0
  40. package/build/build-cjs/booking-wizard/features/summary/summary-slice.d.ts +14 -17
  41. package/build/build-cjs/booking-wizard/features/summary/summary.d.ts +4 -5
  42. package/build/build-cjs/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +95 -45
  43. package/build/build-cjs/booking-wizard/features/travelers-form/travelers-form.d.ts +4 -5
  44. package/build/build-cjs/booking-wizard/features/travelers-form/type-ahead-input.d.ts +16 -15
  45. package/build/build-cjs/booking-wizard/features/travelers-form/validate-form.d.ts +7 -4
  46. package/build/build-cjs/booking-wizard/index.d.ts +12 -11
  47. package/build/build-cjs/booking-wizard/settings-context.d.ts +5 -6
  48. package/build/build-cjs/booking-wizard/store.d.ts +41 -25
  49. package/build/build-cjs/booking-wizard/types.d.ts +111 -59
  50. package/build/build-cjs/booking-wizard/utils/class-util.d.ts +1 -1
  51. package/build/build-cjs/booking-wizard/utils/localization-util.d.ts +1 -1
  52. package/build/build-cjs/booking-wizard/utils/query-string-util.d.ts +21 -2
  53. package/build/build-cjs/booking-wizard/utils/tide-api-utils.d.ts +2 -2
  54. package/build/build-cjs/index.d.ts +2 -2
  55. package/build/build-cjs/index.js +13642 -1886
  56. package/build/build-esm/booking-wizard/components/icon.d.ts +7 -7
  57. package/build/build-esm/booking-wizard/components/labeled-input.d.ts +18 -18
  58. package/build/build-esm/booking-wizard/components/labeled-select.d.ts +21 -21
  59. package/build/build-esm/booking-wizard/components/message.d.ts +9 -8
  60. package/build/build-esm/booking-wizard/components/product-card.d.ts +8 -9
  61. package/build/build-esm/booking-wizard/components/rating.d.ts +6 -6
  62. package/build/build-esm/booking-wizard/components/step-indicator.d.ts +6 -6
  63. package/build/build-esm/booking-wizard/components/step-route.d.ts +9 -9
  64. package/build/build-esm/booking-wizard/features/booking/api.d.ts +21 -0
  65. package/build/build-esm/booking-wizard/features/booking/booking-slice.d.ts +124 -18
  66. package/build/build-esm/booking-wizard/features/booking/booking.d.ts +8 -9
  67. package/build/build-esm/booking-wizard/features/booking/selectors.d.ts +208 -0
  68. package/build/build-esm/booking-wizard/features/confirmation/confirmation.d.ts +4 -5
  69. package/build/build-esm/booking-wizard/features/error/error.d.ts +4 -5
  70. package/build/build-esm/booking-wizard/features/price-details/price-details-api.d.ts +12 -6
  71. package/build/build-esm/booking-wizard/features/price-details/price-details-slice.d.ts +105 -10
  72. package/build/build-esm/booking-wizard/features/price-details/util.d.ts +5 -0
  73. package/build/build-esm/booking-wizard/features/product-options/no-options.d.ts +2 -0
  74. package/build/build-esm/booking-wizard/features/product-options/none-option.d.ts +17 -0
  75. package/build/build-esm/booking-wizard/features/product-options/option-booking-group.d.ts +18 -0
  76. package/build/build-esm/booking-wizard/features/product-options/option-item.d.ts +11 -0
  77. package/build/build-esm/booking-wizard/features/product-options/option-pax-card.d.ts +9 -0
  78. package/build/build-esm/booking-wizard/features/product-options/option-pax-group.d.ts +20 -0
  79. package/build/build-esm/booking-wizard/features/product-options/option-room.d.ts +16 -0
  80. package/build/build-esm/booking-wizard/features/product-options/option-unit-group.d.ts +20 -0
  81. package/build/build-esm/booking-wizard/features/product-options/option-units-card.d.ts +9 -0
  82. package/build/build-esm/booking-wizard/features/product-options/options-form.d.ts +4 -5
  83. package/build/build-esm/booking-wizard/features/product-options/validate-form.d.ts +2 -2
  84. package/build/build-esm/booking-wizard/features/sidebar/index.d.ts +7 -3
  85. package/build/build-esm/booking-wizard/features/sidebar/sidebar-flight.d.ts +8 -0
  86. package/build/build-esm/booking-wizard/features/sidebar/sidebar-util.d.ts +28 -4
  87. package/build/build-esm/booking-wizard/features/sidebar/sidebar.d.ts +29 -21
  88. package/build/build-esm/booking-wizard/features/summary/summary-booking-option-pax.d.ts +7 -0
  89. package/build/build-esm/booking-wizard/features/summary/summary-booking-option-unit.d.ts +7 -0
  90. package/build/build-esm/booking-wizard/features/summary/summary-flight.d.ts +8 -0
  91. package/build/build-esm/booking-wizard/features/summary/summary-per-booking-option-group.d.ts +10 -0
  92. package/build/build-esm/booking-wizard/features/summary/summary-per-pax-option-group.d.ts +10 -0
  93. package/build/build-esm/booking-wizard/features/summary/summary-per-unit-option-group.d.ts +10 -0
  94. package/build/build-esm/booking-wizard/features/summary/summary-slice.d.ts +14 -17
  95. package/build/build-esm/booking-wizard/features/summary/summary.d.ts +4 -5
  96. package/build/build-esm/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +95 -45
  97. package/build/build-esm/booking-wizard/features/travelers-form/travelers-form.d.ts +4 -5
  98. package/build/build-esm/booking-wizard/features/travelers-form/type-ahead-input.d.ts +16 -15
  99. package/build/build-esm/booking-wizard/features/travelers-form/validate-form.d.ts +7 -4
  100. package/build/build-esm/booking-wizard/index.d.ts +12 -11
  101. package/build/build-esm/booking-wizard/settings-context.d.ts +5 -6
  102. package/build/build-esm/booking-wizard/store.d.ts +41 -25
  103. package/build/build-esm/booking-wizard/types.d.ts +111 -59
  104. package/build/build-esm/booking-wizard/utils/class-util.d.ts +1 -1
  105. package/build/build-esm/booking-wizard/utils/localization-util.d.ts +1 -1
  106. package/build/build-esm/booking-wizard/utils/query-string-util.d.ts +21 -2
  107. package/build/build-esm/booking-wizard/utils/tide-api-utils.d.ts +2 -2
  108. package/build/build-esm/index.d.ts +2 -2
  109. package/build/build-esm/index.js +13478 -1875
  110. package/package.json +8 -4
  111. package/rollup.config.js +1 -6
  112. package/src/booking-wizard/components/message.tsx +14 -8
  113. package/src/booking-wizard/components/product-card.tsx +10 -39
  114. package/src/booking-wizard/components/step-indicator.tsx +1 -1
  115. package/src/booking-wizard/components/step-route.tsx +1 -1
  116. package/src/booking-wizard/features/booking/api.ts +44 -0
  117. package/src/booking-wizard/features/booking/booking-slice.ts +274 -40
  118. package/src/booking-wizard/features/booking/booking.tsx +193 -57
  119. package/src/booking-wizard/features/booking/selectors.ts +328 -0
  120. package/src/booking-wizard/features/confirmation/confirmation.tsx +22 -11
  121. package/src/booking-wizard/features/error/error.tsx +15 -2
  122. package/src/booking-wizard/features/price-details/price-details-api.ts +12 -6
  123. package/src/booking-wizard/features/price-details/price-details-slice.ts +80 -50
  124. package/src/booking-wizard/features/price-details/util.ts +135 -0
  125. package/src/booking-wizard/features/product-options/no-options.tsx +18 -0
  126. package/src/booking-wizard/features/product-options/none-option.tsx +118 -0
  127. package/src/booking-wizard/features/product-options/option-booking-group.tsx +210 -0
  128. package/src/booking-wizard/features/product-options/option-item.tsx +321 -0
  129. package/src/booking-wizard/features/product-options/option-pax-card.tsx +102 -0
  130. package/src/booking-wizard/features/product-options/option-pax-group.tsx +169 -0
  131. package/src/booking-wizard/features/product-options/option-room.tsx +300 -0
  132. package/src/booking-wizard/features/product-options/option-unit-group.tsx +192 -0
  133. package/src/booking-wizard/features/product-options/option-units-card.tsx +100 -0
  134. package/src/booking-wizard/features/product-options/options-form.tsx +226 -48
  135. package/src/booking-wizard/features/sidebar/index.tsx +43 -20
  136. package/src/booking-wizard/features/sidebar/sidebar-flight.tsx +66 -0
  137. package/src/booking-wizard/features/sidebar/sidebar-util.ts +81 -39
  138. package/src/booking-wizard/features/sidebar/sidebar.tsx +150 -100
  139. package/src/booking-wizard/features/summary/summary-booking-option-pax.tsx +25 -0
  140. package/src/booking-wizard/features/summary/summary-booking-option-unit.tsx +25 -0
  141. package/src/booking-wizard/features/summary/summary-flight.tsx +35 -0
  142. package/src/booking-wizard/features/summary/summary-per-booking-option-group.tsx +57 -0
  143. package/src/booking-wizard/features/summary/summary-per-pax-option-group.tsx +51 -0
  144. package/src/booking-wizard/features/summary/summary-per-unit-option-group.tsx +54 -0
  145. package/src/booking-wizard/features/summary/summary-slice.ts +1 -134
  146. package/src/booking-wizard/features/summary/summary.tsx +521 -134
  147. package/src/booking-wizard/features/travelers-form/travelers-form-slice.ts +55 -56
  148. package/src/booking-wizard/features/travelers-form/travelers-form.tsx +202 -94
  149. package/src/booking-wizard/features/travelers-form/type-ahead-input.tsx +23 -3
  150. package/src/booking-wizard/features/travelers-form/validate-form.ts +40 -3
  151. package/src/booking-wizard/index.tsx +5 -6
  152. package/src/booking-wizard/settings-context.ts +33 -5
  153. package/src/booking-wizard/store.ts +5 -4
  154. package/src/booking-wizard/translations/translations.json +95 -61
  155. package/src/booking-wizard/types.ts +67 -10
  156. package/src/booking-wizard/utils/query-string-util.ts +42 -0
  157. package/build/build-cjs/booking-wizard/features/product-options/checkbox.d.ts +0 -11
  158. package/build/build-cjs/booking-wizard/features/product-options/option-details.d.ts +0 -11
  159. package/build/build-cjs/booking-wizard/features/product-options/product-options-api.d.ts +0 -26
  160. package/build/build-cjs/booking-wizard/features/product-options/product-options-slice.d.ts +0 -37
  161. package/build/build-cjs/booking-wizard/features/product-options/radio-button.d.ts +0 -10
  162. package/build/build-cjs/booking-wizard/features/product-options/rooms-slice.d.ts +0 -12
  163. package/build/build-cjs/booking-wizard/features/product-options/tree-level.d.ts +0 -7
  164. package/build/build-esm/booking-wizard/features/product-options/checkbox.d.ts +0 -11
  165. package/build/build-esm/booking-wizard/features/product-options/option-details.d.ts +0 -11
  166. package/build/build-esm/booking-wizard/features/product-options/product-options-api.d.ts +0 -26
  167. package/build/build-esm/booking-wizard/features/product-options/product-options-slice.d.ts +0 -37
  168. package/build/build-esm/booking-wizard/features/product-options/radio-button.d.ts +0 -10
  169. package/build/build-esm/booking-wizard/features/product-options/rooms-slice.d.ts +0 -12
  170. package/build/build-esm/booking-wizard/features/product-options/tree-level.d.ts +0 -7
  171. package/src/booking-wizard/features/product-options/checkbox.tsx +0 -38
  172. package/src/booking-wizard/features/product-options/option-details.tsx +0 -65
  173. package/src/booking-wizard/features/product-options/product-options-api.ts +0 -148
  174. package/src/booking-wizard/features/product-options/product-options-slice.ts +0 -149
  175. package/src/booking-wizard/features/product-options/radio-button.tsx +0 -35
  176. package/src/booking-wizard/features/product-options/rooms-slice.ts +0 -28
  177. package/src/booking-wizard/features/product-options/tree-level.tsx +0 -118
@@ -2,13 +2,14 @@ import React, { useContext } from "react";
2
2
  import {
3
3
  selectBookingNumber,
4
4
  selectBookingQueryString,
5
- } from "../booking/booking-slice";
5
+ } from "../booking/selectors";
6
6
 
7
7
  import Message from "../../components/message";
8
8
  import SettingsContext from "../../settings-context";
9
9
  import { navigate } from "@reach/router";
10
10
  import translations from "../../translations/translations.json";
11
11
  import { useSelector } from "react-redux";
12
+ import Icon from "../../components/icon";
12
13
 
13
14
  interface ConfirmationProps {}
14
15
 
@@ -20,26 +21,36 @@ const Confirmation: React.FC<ConfirmationProps> = () => {
20
21
 
21
22
  if (!bookingNumber) {
22
23
  navigate(
23
- `${settings.basePath}${settings.errorPathSuffix}?${bookingQueryString}`
24
+ `${settings.basePath}${settings.error.pathSuffix}?${bookingQueryString}`
24
25
  );
25
26
  }
26
27
 
27
28
  return (
28
- <div className="form">
29
+ <div className="form" id="booking--step4">
29
30
  <div className="form__region">
30
31
  <div className="form__row">
31
32
  <div className="form__group">
32
33
  <Message
33
34
  type="success"
34
- title={`Uw boeking met nummer ${bookingNumber} is ingediend`}
35
+ title={`${translations.CONFIRMATION.TITLE_TEXT1}${bookingNumber}${translations.CONFIRMATION.TITLE_TEXT2}`}
35
36
  actionComponent={
36
- <a
37
- href="/"
38
- title={translations.CONFIRMATION.HOME}
39
- className="cta"
40
- >
41
- {translations.CONFIRMATION.HOME}
42
- </a>
37
+ <div className="sm">
38
+ <a
39
+ href={`tel://${settings.companyContactPhone}`}
40
+ className="sm__icon"
41
+ >
42
+ <Icon name="tel" />
43
+ </a>
44
+ <a
45
+ href={`mailto://${settings.companyContactEmail}`}
46
+ className="sm__icon"
47
+ >
48
+ <Icon name="mail" />
49
+ </a>
50
+ <a href="/" className="sm__icon">
51
+ <Icon name="home" />
52
+ </a>
53
+ </div>
43
54
  }
44
55
  >
45
56
  <p>
@@ -1,19 +1,32 @@
1
1
  import Message from "../../components/message";
2
2
  import React from "react";
3
3
  import SettingsContext from "../../settings-context";
4
- import { selectBookingQueryString } from "../booking/booking-slice";
4
+ import { setIsRetry } from "../booking/booking-slice";
5
5
  import translations from "../../translations/translations.json";
6
6
  import { useContext } from "react";
7
7
  import { useSelector } from "react-redux";
8
+ import { navigate } from "@reach/router";
9
+ import { useAppDispatch } from "../../store";
10
+ import { selectBookingQueryString } from "../booking/selectors";
8
11
 
9
12
  interface ErrorProps {}
10
13
 
11
14
  const Error: React.FC<ErrorProps> = () => {
15
+ const dispatch = useAppDispatch();
16
+
12
17
  const settings = useContext(SettingsContext);
13
18
  const bookingQueryString = useSelector(selectBookingQueryString);
14
19
 
15
20
  const tryAgainUrl = `${settings.basePath}?${bookingQueryString}`;
16
21
 
22
+ const handleClick: React.MouseEventHandler<HTMLAnchorElement> = (e) => {
23
+ e.preventDefault();
24
+
25
+ dispatch(setIsRetry(true));
26
+
27
+ navigate(tryAgainUrl);
28
+ };
29
+
17
30
  return (
18
31
  <div className="form">
19
32
  <div className="form__region">
@@ -24,7 +37,7 @@ const Error: React.FC<ErrorProps> = () => {
24
37
  title="Er liep iets mis..."
25
38
  actionComponent={
26
39
  <a
27
- href={tryAgainUrl}
40
+ onClick={handleClick}
28
41
  title={translations.ERROR.TRY_AGAIN}
29
42
  className="cta"
30
43
  >
@@ -1,12 +1,18 @@
1
- import { getPackagePriceDetails } from "@qite/tide-client";
2
- import { PackagePriceDetailsRequest } from "@qite/tide-client/src/types/offer";
1
+ import { priceDetails } from "@qite/tide-client";
2
+ import {
3
+ BookingPackageBookRequest,
4
+ BookingPackageRequest,
5
+ BookingPriceDetails,
6
+ } from "@qite/tide-client/build/types";
3
7
  import { buildTideClientConfig } from "../../utils/tide-api-utils";
4
8
 
5
- export const fetchPriceDetails = async (
6
- request: PackagePriceDetailsRequest
7
- ) => {
9
+ const fetchPriceDetails = async (
10
+ request: BookingPackageRequest<BookingPackageBookRequest>,
11
+ signal: AbortSignal
12
+ ): Promise<BookingPriceDetails> => {
8
13
  const tideClientConfig = buildTideClientConfig();
9
- return await getPackagePriceDetails(tideClientConfig, request);
14
+
15
+ return await priceDetails(tideClientConfig, request, signal);
10
16
  };
11
17
 
12
18
  const priceDetailsApi = {
@@ -1,81 +1,98 @@
1
- import { PackagePriceDetailsRequest, PriceDetail } from "@qite/tide-client";
2
- import { RootState, store } from "../../store";
1
+ import { RootState } from "../../store";
3
2
  import {
4
3
  createAsyncThunk,
5
- createEntityAdapter,
6
4
  createSelector,
7
5
  createSlice,
6
+ PayloadAction,
8
7
  } from "@reduxjs/toolkit";
9
- import { isNil, sum } from "lodash";
8
+ import { sum } from "lodash";
10
9
 
11
10
  import priceDetailsApi from "./price-details-api";
12
- import { selectCacheKey } from "../booking/booking-slice";
13
- import { selectRooms } from "../product-options/rooms-slice";
14
- import { selectSelectedOptions } from "../product-options/product-options-slice";
15
- import { selectTravelerAges } from "../travelers-form/travelers-form-slice";
11
+ import { setPackage } from "../booking/booking-slice";
12
+ import {
13
+ selectBookingPackageBookRequest,
14
+ selectPackageDetails,
15
+ } from "../booking/selectors";
16
+ import {
17
+ BookingPriceDetail,
18
+ BookingPriceDetails,
19
+ BookingProductNotification,
20
+ } from "@qite/tide-client/build/types";
21
+ import { updatePackageDetails } from "./util";
22
+
23
+ export interface PriceDetailsState {
24
+ priceDetails: BookingPriceDetail[];
25
+ notifications: BookingProductNotification[];
26
+ deposit?: number;
27
+ isBusy: boolean;
28
+ }
16
29
 
17
30
  export const fetchPriceDetails = createAsyncThunk(
18
31
  "priceDetails/fetchPriceDetails",
19
- async (request?: PackagePriceDetailsRequest) => {
20
- if (!isNil(request)) {
21
- return await priceDetailsApi.fetchPriceDetails(request);
22
- } else {
23
- const state = store.getState();
24
- const cacheKey = selectCacheKey(state) ?? "";
25
- const optionGuids = selectSelectedOptions(state).map(
26
- (option) => option.guid
27
- );
28
- const travelerAges = selectTravelerAges(state);
29
- const rooms = selectRooms(state);
32
+ async (_, { dispatch, getState, signal }) => {
33
+ dispatch(setFetchingPriceDetails(true));
34
+ dispatch(resetPriceDetails());
30
35
 
31
- if (rooms.length === 0) {
32
- throw Error("No rooms available.");
33
- }
36
+ const state = getState() as RootState;
37
+
38
+ const request = selectBookingPackageBookRequest(state);
34
39
 
35
- return await priceDetailsApi.fetchPriceDetails({
36
- packageSearchResultCacheKey: cacheKey,
37
- officeId: 1,
38
- language: "nl-BE",
39
- optionGuids,
40
- rooms: [{ id: rooms[0].id, travelerAges: travelerAges }],
41
- });
40
+ if (!request) {
41
+ throw Error("Product not available.");
42
42
  }
43
- }
44
- );
45
43
 
46
- const priceDetailsAdapter = createEntityAdapter<PriceDetail>({
47
- selectId: (priceDetail) =>
48
- `${priceDetail.productCode}_${priceDetail.priceDescription}`,
49
- sortComparer: (a, b) => {
50
- const productCodeComparison = a.productCode.localeCompare(b.productCode);
44
+ const priceDetails: BookingPriceDetails =
45
+ await priceDetailsApi.fetchPriceDetails(request, signal);
46
+
47
+ dispatch(setFetchingPriceDetails(false));
51
48
 
52
- if (productCodeComparison !== 0) {
53
- return productCodeComparison;
49
+ const packageDetails = selectPackageDetails(state);
50
+ if (packageDetails) {
51
+ const updatedPackageDetails = updatePackageDetails(
52
+ packageDetails,
53
+ priceDetails.changedLines
54
+ );
55
+ dispatch(setPackage(updatedPackageDetails));
54
56
  }
55
57
 
56
- return a.priceDescription.localeCompare(b.priceDescription);
57
- },
58
- });
58
+ return priceDetails;
59
+ }
60
+ );
59
61
 
60
62
  const priceDetailsSlice = createSlice({
61
63
  name: "priceDetails",
62
- initialState: priceDetailsAdapter.getInitialState(),
63
- reducers: {},
64
+ initialState: <PriceDetailsState>{
65
+ priceDetails: [],
66
+ notifications: [],
67
+ isBusy: false,
68
+ },
69
+ reducers: {
70
+ setFetchingPriceDetails(state, action: PayloadAction<boolean>) {
71
+ state.isBusy = action.payload;
72
+ },
73
+ setNotifications(
74
+ state,
75
+ action: PayloadAction<BookingProductNotification[]>
76
+ ) {
77
+ state.notifications = action.payload;
78
+ },
79
+ resetPriceDetails(state, _: PayloadAction<void>) {
80
+ state.priceDetails = [];
81
+ },
82
+ },
64
83
  extraReducers: (builder) => {
65
84
  builder.addCase(fetchPriceDetails.fulfilled, (state, action) => {
66
85
  if (action.payload) {
67
- priceDetailsAdapter.setAll(state, action.payload);
86
+ state.deposit = action.payload.deposit;
87
+ state.priceDetails = action.payload.details;
88
+ state.notifications = action.payload.notifications;
68
89
  }
69
90
  });
70
91
  },
71
92
  });
72
93
 
73
- const priceDetailsSelectors = priceDetailsAdapter.getSelectors<RootState>(
74
- (state) => state.priceDetails
75
- );
76
-
77
- export const selectPriceDetails = () =>
78
- priceDetailsSelectors.selectAll(store.getState());
94
+ export const selectPriceDetails = (state: RootState) =>
95
+ state.priceDetails.priceDetails;
79
96
 
80
97
  export const selectPackagePriceDetails = createSelector(
81
98
  selectPriceDetails,
@@ -116,4 +133,17 @@ export const selectTotalPrice = createSelector(
116
133
  ])
117
134
  );
118
135
 
136
+ export const selectDeposit = (state: RootState) => state.priceDetails.deposit;
137
+
138
+ export const selectIsFetchingPriceDetails = (state: RootState) =>
139
+ state.priceDetails.isBusy;
140
+
141
+ export const selectNotifications = (state: RootState) =>
142
+ state.priceDetails.notifications;
143
+
144
+ const { setFetchingPriceDetails } = priceDetailsSlice.actions;
145
+
146
+ export const { resetPriceDetails, setNotifications } =
147
+ priceDetailsSlice.actions;
148
+
119
149
  export default priceDetailsSlice.reducer;
@@ -0,0 +1,135 @@
1
+ import {
2
+ BookingPackage,
3
+ ChangedLine,
4
+ BookingOptionPax,
5
+ BookingOptionGroup,
6
+ PerPaxPackageOption,
7
+ BookingOptionUnit,
8
+ PerUnitPackageOption,
9
+ PerBookingPackageOption,
10
+ } from "@qite/tide-client/build/types";
11
+ import { BookingPackageOption } from "@qite/tide-client/build/types/offer/booking-v2/shared/booking-package-option";
12
+
13
+ export const updatePackageDetails = (
14
+ packageDetails: BookingPackage,
15
+ changedLines: ChangedLine[]
16
+ ): BookingPackage => {
17
+ return {
18
+ ...packageDetails,
19
+ options: packageDetails.options.map((opt) => {
20
+ return {
21
+ ...opt,
22
+ groups: opt.isSelected
23
+ ? updateBookingGroups(opt.groups, changedLines)
24
+ : opt.groups,
25
+ optionUnits: opt.isSelected
26
+ ? updateOptionUnits(opt.optionUnits, changedLines)
27
+ : opt.optionUnits,
28
+ optionPax: opt.isSelected
29
+ ? updateOptionPax(opt.optionPax, changedLines)
30
+ : opt.optionPax,
31
+ } as BookingPackageOption;
32
+ }),
33
+ };
34
+ };
35
+
36
+ // PAX
37
+ const updateOptionPax = (
38
+ pax: BookingOptionPax[],
39
+ changedLines: ChangedLine[]
40
+ ): BookingOptionPax[] => {
41
+ return pax.map((p) => ({
42
+ ...p,
43
+ groups: updatePaxGroups(p.groups, changedLines),
44
+ }));
45
+ };
46
+
47
+ const updatePaxGroups = (
48
+ groups: BookingOptionGroup<PerPaxPackageOption>[],
49
+ changedLines: ChangedLine[]
50
+ ): BookingOptionGroup<PerPaxPackageOption>[] => {
51
+ return groups.map((g) => ({
52
+ ...g,
53
+ options: g.options.map((o) => ({
54
+ ...o,
55
+ groups: updatePaxGroups(o.groups, changedLines),
56
+ line: {
57
+ ...o.line,
58
+ price:
59
+ changedLines.find((cl) => cl.entryLineGuid === o.line.entryLineGuid)
60
+ ?.price ?? o.line.price,
61
+ },
62
+ alternatives: o.alternatives.map((a) => ({
63
+ ...a,
64
+ price:
65
+ changedLines.find((cl) => cl.entryLineGuid === a.entryLineGuid)
66
+ ?.price ?? a.price,
67
+ })),
68
+ })),
69
+ }));
70
+ };
71
+
72
+ // UNITS
73
+ const updateOptionUnits = (
74
+ units: BookingOptionUnit[],
75
+ changedLines: ChangedLine[]
76
+ ): BookingOptionUnit[] => {
77
+ return units.map((u) => ({
78
+ ...u,
79
+ groups: updateUnitGroups(u.groups, changedLines),
80
+ }));
81
+ };
82
+
83
+ const updateUnitGroups = (
84
+ groups: BookingOptionGroup<PerUnitPackageOption>[],
85
+ changedLines: ChangedLine[]
86
+ ): BookingOptionGroup<PerUnitPackageOption>[] => {
87
+ return groups.map((g) => ({
88
+ ...g,
89
+ options: g.options.map((o) => ({
90
+ ...o,
91
+ groups: updateUnitGroups(o.groups, changedLines),
92
+ pax: updateOptionPax(o.pax, changedLines),
93
+ line: {
94
+ ...o.line,
95
+ price:
96
+ changedLines.find((cl) => cl.entryLineGuid === o.line.entryLineGuid)
97
+ ?.price ?? o.line.price,
98
+ },
99
+ alternatives: o.alternatives.map((a) => ({
100
+ ...a,
101
+ price:
102
+ changedLines.find((cl) => cl.entryLineGuid === a.entryLineGuid)
103
+ ?.price ?? a.price,
104
+ })),
105
+ })),
106
+ }));
107
+ };
108
+
109
+ // BOOKING
110
+ const updateBookingGroups = (
111
+ groups: BookingOptionGroup<PerBookingPackageOption>[],
112
+ changedLines: ChangedLine[]
113
+ ): BookingOptionGroup<PerBookingPackageOption>[] => {
114
+ return groups.map((g) => ({
115
+ ...g,
116
+ options: g.options.map((o) => ({
117
+ ...o,
118
+ groups: updateBookingGroups(o.groups, changedLines),
119
+ units: updateOptionUnits(o.units, changedLines),
120
+ pax: updateOptionPax(o.pax, changedLines),
121
+ line: {
122
+ ...o.line,
123
+ price:
124
+ changedLines.find((cl) => cl.entryLineGuid === o.line.entryLineGuid)
125
+ ?.price ?? o.line.price,
126
+ },
127
+ alternatives: o.alternatives.map((a) => ({
128
+ ...a,
129
+ price:
130
+ changedLines.find((cl) => cl.entryLineGuid === a.entryLineGuid)
131
+ ?.price ?? a.price,
132
+ })),
133
+ })),
134
+ }));
135
+ };
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import Message from "../../components/message";
3
+ import translations from "../../translations/translations.json";
4
+
5
+ const NoOptions = () => {
6
+ return (
7
+ <div className="form__group">
8
+ <Message
9
+ type="success"
10
+ title={translations.OPTIONS_FORM.NO_OPTIONS_TITLE}
11
+ >
12
+ <p>{translations.OPTIONS_FORM.NO_OPTIONS_MESSAGE}</p>
13
+ </Message>
14
+ </div>
15
+ );
16
+ };
17
+
18
+ export default NoOptions;
@@ -0,0 +1,118 @@
1
+ import {
2
+ BookingOptionGroup,
3
+ PerBookingPackageOption,
4
+ PerPaxPackageOption,
5
+ PerUnitPackageOption,
6
+ } from "@qite/tide-client/build/types";
7
+ import React from "react";
8
+ import { buildClassName } from "../../utils/class-util";
9
+ import translations from "../../translations/translations.json";
10
+ import { formatPrice } from "../../utils/localization-util";
11
+
12
+ interface NoneOptionProps {
13
+ group:
14
+ | BookingOptionGroup<PerBookingPackageOption>
15
+ | BookingOptionGroup<PerUnitPackageOption>
16
+ | BookingOptionGroup<PerPaxPackageOption>;
17
+ parentId: string;
18
+ handleNoneSelectionChanged: () => void;
19
+ }
20
+
21
+ const NoneOption: React.FC<NoneOptionProps> = ({
22
+ group,
23
+ parentId,
24
+ handleNoneSelectionChanged,
25
+ }) => {
26
+ const selectedOption = group.options.find((x) => x.isSelected);
27
+ const showNoneOption = group.options.some((x) => x.requirementType === 2);
28
+ const noneSelected = !selectedOption;
29
+ const priceDifferencetext = selectedOption
30
+ ? `- ${formatPrice(Math.abs(selectedOption.line.price))}`
31
+ : "";
32
+
33
+ return (
34
+ <>
35
+ {showNoneOption && (
36
+ <tr>
37
+ <td>
38
+ <div
39
+ className={buildClassName([
40
+ "tree",
41
+ noneSelected && "tree--selected",
42
+ ])}
43
+ >
44
+ <div className="tree__level">
45
+ <div className="tree__header">
46
+ <div className="tree__description-collapse">
47
+ <div className="radiobutton">
48
+ <div className="radiobutton__label">
49
+ <input
50
+ type="radio"
51
+ value={undefined}
52
+ id={`${parentId}_NONE`}
53
+ name={parentId}
54
+ className={buildClassName([
55
+ "radiobutton__input",
56
+ "radiobutton__input--parent",
57
+ ])}
58
+ defaultChecked={noneSelected}
59
+ onChange={handleNoneSelectionChanged}
60
+ ></input>
61
+ <span className="radiobutton__label-text">
62
+ <div className="date-list">
63
+ <span
64
+ className={buildClassName([
65
+ "date-list__item",
66
+ "date-list__item--none",
67
+ ])}
68
+ ></span>
69
+ </div>
70
+ </span>
71
+ <div className="tree__columns-actions">
72
+ <div className="tree__columns">
73
+ <div className="tree__column">
74
+ <label
75
+ htmlFor={`${parentId}_NONE`}
76
+ className={buildClassName([
77
+ "tree__product-name",
78
+ "tree__product-name--none",
79
+ ])}
80
+ >
81
+ {translations.OPTIONS_FORM.NONE}
82
+ </label>
83
+ </div>
84
+ <div className="tree__column"></div>
85
+ <div className="tree__column"></div>
86
+ <div
87
+ className={buildClassName([
88
+ "tree__column",
89
+ "tree__column--price",
90
+ ])}
91
+ >
92
+ {!noneSelected && (
93
+ <span
94
+ className={buildClassName([
95
+ "price",
96
+ "price--decrease",
97
+ ])}
98
+ >
99
+ {priceDifferencetext}
100
+ </span>
101
+ )}
102
+ </div>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </div>
110
+ </div>
111
+ </td>
112
+ </tr>
113
+ )}
114
+ </>
115
+ );
116
+ };
117
+
118
+ export default NoneOption;