@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
@@ -3,20 +3,30 @@ import { navigate, Router, useLocation } from "@reach/router";
3
3
  import {
4
4
  getDateFromParams,
5
5
  getNumberFromParams,
6
+ getNumbersFromParams,
7
+ getRoomsFromParams,
8
+ getStringFromParams,
6
9
  } from "../../utils/query-string-util";
7
10
  import {
8
- selectBookingAttributes,
9
- selectProductAttributes,
11
+ fetchPackage,
12
+ setAgentAdressId,
13
+ setBookingOptions,
10
14
  setBookingAttributes,
15
+ setBookingNumber,
16
+ setCalculateDeposit,
17
+ setGeneratePaymentUrl,
18
+ setIsRetry,
11
19
  setOfficeId,
12
20
  setProductAttributes,
21
+ setSkipPayment,
22
+ setTagIds,
23
+ setBookingType,
13
24
  } from "./booking-slice";
14
- import { useDispatch, useSelector } from "react-redux";
25
+ import { useSelector } from "react-redux";
15
26
 
16
27
  import Confirmation from "../confirmation/confirmation";
17
28
  import Error from "../error/error";
18
29
  import OptionsForm from "../product-options/options-form";
19
- import ProductCard from "../../components/product-card";
20
30
  import SettingsContext from "../../settings-context";
21
31
  import Sidebar from "../sidebar";
22
32
  import StepRoute from "../../components/step-route";
@@ -24,119 +34,224 @@ import Summary from "../summary/summary";
24
34
  import TravelersForm from "../travelers-form/travelers-form";
25
35
  import translations from "../../translations/translations.json";
26
36
  import { useEffect } from "react";
27
- import { fetchProductOptions } from "../product-options/product-options-slice";
37
+ import { isNil } from "lodash";
38
+ import { useAppDispatch } from "../../store";
39
+ import {
40
+ selectBookingAttributes,
41
+ selectBookingNumber,
42
+ selectBookingRooms,
43
+ selectIsRetry,
44
+ selectIsUnavailable,
45
+ selectPackageDetails,
46
+ selectProductAttributes,
47
+ } from "./selectors";
28
48
 
29
49
  interface BookingProps {
30
- productId: number;
50
+ productCode: string;
31
51
  productName: string;
32
- productDescription?: string;
33
52
  thumbnailUrl?: string;
34
53
  }
35
54
 
36
55
  const Booking: React.FC<BookingProps> = ({
37
- productId,
56
+ productCode,
38
57
  productName,
39
- productDescription,
40
58
  thumbnailUrl,
41
59
  }) => {
42
60
  const {
43
61
  officeId,
44
- productPath,
62
+ bookingOptions,
45
63
  basePath,
46
- optionsPathSuffix,
47
- summaryPathSuffix,
48
- confirmationPathSuffix,
49
- errorPathSuffix,
64
+ options,
65
+ summary,
66
+ confirmation,
67
+ error,
68
+ showSidebarDeposit,
69
+ includeFlights,
70
+ loaderComponent,
71
+ skipPaymentWithAgent,
72
+ generatePaymentUrl,
73
+ tagIds,
74
+ agentAdressId,
50
75
  } = useContext(SettingsContext);
51
76
 
52
- const dispatch = useDispatch();
53
-
77
+ const dispatch = useAppDispatch();
54
78
  const location = useLocation();
55
79
 
56
80
  const productAttributes = useSelector(selectProductAttributes);
57
81
  const bookingAttributes = useSelector(selectBookingAttributes);
82
+ const rooms = useSelector(selectBookingRooms);
83
+ const bookingNumber = useSelector(selectBookingNumber);
84
+ const isRetry = useSelector(selectIsRetry);
85
+ const packageDetails = useSelector(selectPackageDetails);
86
+ const isUnvailable = useSelector(selectIsUnavailable);
58
87
 
59
88
  useEffect(() => {
60
- dispatch(fetchProductOptions());
61
- }, [productAttributes, bookingAttributes]);
62
-
63
- useEffect(() => {
64
- if (productId) {
65
- dispatch(
66
- setProductAttributes({
67
- productId,
68
- })
69
- );
70
- } else {
71
- navigate(productPath);
72
- }
73
- }, [productId, setProductAttributes]);
74
-
75
- useEffect(() => {
76
- dispatch(setOfficeId(officeId));
77
- }, [officeId, setOfficeId]);
89
+ dispatch(setSkipPayment(skipPaymentWithAgent ?? false));
90
+ dispatch(setGeneratePaymentUrl(generatePaymentUrl ?? false));
91
+ }, [skipPaymentWithAgent, generatePaymentUrl]);
78
92
 
79
93
  useEffect(() => {
80
94
  const params = new URLSearchParams(location.search);
81
95
  const startDate = getDateFromParams(params, "startDate");
82
96
  const endDate = getDateFromParams(params, "endDate");
83
- const accommodation = params.get("accommodation");
84
- const regime = params.get("regime");
85
97
  const catalog = getNumberFromParams(params, "catalog");
98
+ const rooms = getRoomsFromParams(params, "rooms");
99
+ const allotmentName = getStringFromParams(params, "allotmentName");
100
+ const allotmentIds = getNumbersFromParams(params, "allotementId");
101
+ const tourCode = getStringFromParams(params, "tourCode");
102
+ const bookingNumber = params.get("bookingNr") ?? undefined;
103
+
104
+ if (!isNil(bookingNumber)) {
105
+ dispatch(setBookingNumber(bookingNumber));
106
+ navigate(
107
+ `${basePath}${confirmation.pathSuffix}?bookingNr=${bookingNumber}`
108
+ );
109
+ }
86
110
 
87
- if (startDate && endDate && accommodation && regime && catalog) {
111
+ if (
112
+ !isNil(startDate) &&
113
+ !isNil(endDate) &&
114
+ !isNil(catalog) &&
115
+ !isNil(rooms)
116
+ ) {
88
117
  dispatch(
89
118
  setBookingAttributes({
90
119
  startDate,
91
120
  endDate,
92
- accommodation,
93
- regime,
94
121
  catalog,
122
+ rooms,
123
+ includeFlights,
124
+ allotmentName,
125
+ allotmentIds,
126
+ tourCode,
95
127
  })
96
128
  );
97
129
  } else {
98
- navigate(productPath);
130
+ console.error(
131
+ "Failure when setting booking attributes",
132
+ startDate,
133
+ endDate,
134
+ catalog,
135
+ rooms
136
+ );
137
+ }
138
+ }, [location.search, setBookingAttributes, setBookingNumber, includeFlights]);
139
+
140
+ useEffect(() => {
141
+ if (
142
+ !productAttributes ||
143
+ !bookingAttributes ||
144
+ !isNil(bookingNumber) ||
145
+ !isRetry
146
+ ) {
147
+ return;
99
148
  }
100
- }, [setBookingAttributes]);
149
+
150
+ // Retried
151
+ dispatch(setIsRetry(false));
152
+
153
+ // Fetch data
154
+ const promise = dispatch(fetchPackage());
155
+ return () => {
156
+ promise.abort();
157
+ };
158
+ }, [isRetry]);
159
+
160
+ useEffect(() => {
161
+ if (!isNil(productCode) && !isNil(productName)) {
162
+ dispatch(
163
+ setProductAttributes({
164
+ productCode,
165
+ productName,
166
+ })
167
+ );
168
+ } else {
169
+ console.error(
170
+ "Failure when setting product attributes",
171
+ productCode,
172
+ productName
173
+ );
174
+ }
175
+ }, [productCode, productName, setProductAttributes]);
176
+
177
+ useEffect(() => {
178
+ dispatch(setOfficeId(officeId));
179
+ dispatch(setBookingOptions(bookingOptions));
180
+ dispatch(setCalculateDeposit(showSidebarDeposit));
181
+ dispatch(setTagIds(tagIds ?? undefined));
182
+ dispatch(setAgentAdressId(agentAdressId ?? undefined));
183
+ if (agentAdressId && agentAdressId != 0) {
184
+ dispatch(setBookingType("b2b"));
185
+ }
186
+ }, [
187
+ officeId,
188
+ bookingOptions,
189
+ showSidebarDeposit,
190
+ setOfficeId,
191
+ setCalculateDeposit,
192
+ tagIds,
193
+ agentAdressId,
194
+ ]);
195
+
196
+ useEffect(() => {
197
+ if (
198
+ !productAttributes ||
199
+ !bookingAttributes ||
200
+ !rooms?.length ||
201
+ !isNil(bookingNumber) ||
202
+ !isNil(packageDetails)
203
+ ) {
204
+ return;
205
+ }
206
+ // Fetch data
207
+ const promise = dispatch(fetchPackage());
208
+ return () => {
209
+ promise.abort();
210
+ };
211
+ }, [
212
+ productAttributes,
213
+ bookingAttributes,
214
+ rooms,
215
+ bookingNumber,
216
+ packageDetails,
217
+ ]);
101
218
 
102
219
  return (
103
220
  <>
104
- {productAttributes && bookingAttributes && (
221
+ {((productAttributes && bookingAttributes && packageDetails) ||
222
+ bookingNumber) && (
105
223
  <div className="booking">
106
- <ProductCard
107
- productName={productName}
108
- productDescription={productDescription}
109
- thumbnailUrl={thumbnailUrl}
110
- />
111
224
  <div className="booking__content">
112
225
  <div className="booking__panel">
113
226
  <Router basepath={basePath}>
114
227
  <StepRoute
115
- path="/"
228
+ path={options.pathSuffix}
116
229
  number={1}
117
- title={translations.STEPS.PERSONAL_DETAILS}
118
- component={<TravelersForm />}
230
+ title={translations.STEPS.TRAVEL_OPTIONS}
231
+ component={<OptionsForm />}
119
232
  />
233
+
120
234
  <StepRoute
121
- path={optionsPathSuffix}
235
+ path="/"
122
236
  number={2}
123
- title={translations.STEPS.TRAVEL_OPTIONS}
124
- component={<OptionsForm />}
237
+ title={translations.STEPS.PERSONAL_DETAILS}
238
+ component={<TravelersForm />}
125
239
  />
240
+
126
241
  <StepRoute
127
- path={summaryPathSuffix}
242
+ path={summary.pathSuffix}
128
243
  number={3}
129
244
  title={translations.STEPS.SUMMARY}
130
245
  component={<Summary />}
131
246
  />
132
247
  <StepRoute
133
- path={confirmationPathSuffix}
248
+ path={confirmation.pathSuffix}
134
249
  number={4}
135
250
  title={translations.STEPS.CONFIRMATION}
136
251
  component={<Confirmation />}
137
252
  />
138
253
  <StepRoute
139
- path={errorPathSuffix}
254
+ path={error.pathSuffix}
140
255
  number={4}
141
256
  title={translations.STEPS.ERROR}
142
257
  component={<Error />}
@@ -144,7 +259,28 @@ const Booking: React.FC<BookingProps> = ({
144
259
  </Router>
145
260
  </div>
146
261
  <div className="backdrop" id="backdrop"></div>
147
- <Sidebar />
262
+ {packageDetails && (
263
+ <Sidebar productName={productName} thumbnailUrl={thumbnailUrl} />
264
+ )}
265
+ </div>
266
+ </div>
267
+ )}
268
+ {!packageDetails && !bookingNumber && !isUnvailable && (
269
+ <div className="booking">
270
+ <div className="booking__loader">
271
+ {loaderComponent}
272
+ <p className="booking__loader-text">
273
+ {translations.MAIN.PREPARING_BOOKING}
274
+ </p>
275
+ </div>
276
+ </div>
277
+ )}
278
+ {isUnvailable && (
279
+ <div className="booking">
280
+ <div className="booking__loader">
281
+ <p className="booking__loader-text">
282
+ {translations.MAIN.PRODUCT_UNAVAILABLE}
283
+ </p>
148
284
  </div>
149
285
  </div>
150
286
  )}
@@ -0,0 +1,328 @@
1
+ import JsonURL from "@jsonurl/jsonurl";
2
+ import { Gender } from "@qite/tide-client";
3
+ import {
4
+ BookingPackageAddress,
5
+ BookingPackageBookRequest,
6
+ BookingPackagePax,
7
+ BookingPackageRequest,
8
+ } from "@qite/tide-client/build/types/offer";
9
+ import { createSelector } from "@reduxjs/toolkit";
10
+ import { format, parseISO } from "date-fns";
11
+ import { omit } from "lodash";
12
+ import { RootState } from "../../store";
13
+ import { Room, Traveler } from "../../types";
14
+ import { selectNotifications } from "../price-details/price-details-slice";
15
+ import {
16
+ selectAgentId,
17
+ selectTravelersFormValues,
18
+ } from "../travelers-form/travelers-form-slice";
19
+
20
+ export const selectGeneratePaymentUrl = (state: RootState) =>
21
+ state.booking.generatePaymentUrl;
22
+
23
+ export const selectSkipPaymentWithAgent = (state: RootState) =>
24
+ state.booking.skipPaymentWithAgent;
25
+
26
+ export const selectIsFetchingProductOptions = (state: RootState) =>
27
+ state.booking.isBusy;
28
+
29
+ export const selectDepartureFlight = (state: RootState) =>
30
+ state.booking.package?.outwardFlights?.find((x) => x.isSelected);
31
+
32
+ export const selectReturnFlight = (state: RootState) =>
33
+ state.booking.package?.returnFlights?.find((x) => x.isSelected);
34
+
35
+ export const selectPackageRooms = (state: RootState) =>
36
+ state.booking.package?.options.find((x) => x.isSelected)?.rooms;
37
+
38
+ export const selectIsOnRequest = (state: RootState) =>
39
+ state.booking.package?.options.find((x) => x.isSelected)?.isOnRequest;
40
+
41
+ export const selectPackageOptionUnits = (state: RootState) =>
42
+ state.booking.package?.options.find((x) => x.isSelected)?.optionUnits;
43
+
44
+ export const selectPackageOptionPax = (state: RootState) =>
45
+ state.booking.package?.options.find((x) => x.isSelected)?.optionPax;
46
+
47
+ export const selectPackageGroups = (state: RootState) =>
48
+ state.booking.package?.options.find((x) => x.isSelected)?.groups;
49
+
50
+ export const selectPackageDetails = (state: RootState) => state.booking.package;
51
+
52
+ export const selectActiveOption = (state: RootState) =>
53
+ state.booking.package?.options.find((x) => x.isSelected);
54
+
55
+ export const selectIsUnavailable = (state: RootState) =>
56
+ state.booking.isUnavailable;
57
+
58
+ export const selectRequestRooms = (state: RootState) =>
59
+ state.booking.package?.options.find((x) => x.isSelected)?.requestRooms;
60
+
61
+ export const selectOfficeId = (state: RootState) => state.booking.officeId;
62
+
63
+ export const selectBookingOptions = (state: RootState) =>
64
+ state.booking.bookingOptions;
65
+
66
+ export const selectBookingType = (state: RootState) =>
67
+ state.booking.bookingType;
68
+
69
+ export const selectTagIds = (state: RootState) => state.booking.tagIds;
70
+
71
+ export const selectAgentAdressId = (state: RootState) =>
72
+ state.booking.agentAdressId;
73
+
74
+ export const selectProductAttributes = (state: RootState) =>
75
+ state.booking.productAttributes;
76
+
77
+ export const selectBookingAttributes = (state: RootState) =>
78
+ state.booking.bookingAttributes;
79
+
80
+ export const selectBookingNumber = (state: RootState) =>
81
+ state.booking.bookingNumber;
82
+
83
+ export const selectBookingRooms = (state: RootState) =>
84
+ state.booking.bookingAttributes?.rooms;
85
+
86
+ export const selectBookingRemarks = (state: RootState) => state.booking.remarks;
87
+
88
+ export const selectVoucherCodes = (state: RootState) =>
89
+ state.booking.voucherCodes;
90
+
91
+ export const selectCalculateDeposit = (state: RootState) =>
92
+ state.booking.calculateDeposit;
93
+
94
+ export const selectIsRetry = (state: RootState) => state.booking.isRetry;
95
+
96
+ export const selectStartDate = (state: RootState) =>
97
+ state.booking.package?.options.find((x) => x.isSelected)?.fromDate;
98
+
99
+ export const selectAgents = (state: RootState) => state.booking.agents;
100
+
101
+ export const selectBookingQuery = (state: RootState) => {
102
+ const bookingAttributes = state.booking.bookingAttributes;
103
+
104
+ if (!bookingAttributes) {
105
+ return undefined;
106
+ }
107
+
108
+ const params: Record<string, string> = {};
109
+ Object.entries(bookingAttributes).forEach(([key, value]) => {
110
+ if (key === "startDate" || key === "endDate") {
111
+ value = format(parseISO(value), "yyyy-MM-dd");
112
+ }
113
+ if (key === "rooms") {
114
+ value = JsonURL.stringify(
115
+ (value as Room[]).map((room) => omit(room, ["children"])),
116
+ {
117
+ AQF: true,
118
+ }
119
+ );
120
+ }
121
+ params[key] = value;
122
+ });
123
+
124
+ return params;
125
+ };
126
+
127
+ export const selectBookingQueryString = createSelector(
128
+ selectBookingQuery,
129
+ (params) => {
130
+ if (!params) {
131
+ return undefined;
132
+ }
133
+
134
+ return Object.keys(params)
135
+ .filter((key) => typeof params[key] !== "undefined")
136
+ .map((key) => `${key}=${params[key]}`)
137
+ .join("&");
138
+ }
139
+ );
140
+
141
+ export const selectMainBookerId = createSelector(
142
+ selectTravelersFormValues,
143
+ (formValues) => formValues?.mainBookerId
144
+ );
145
+
146
+ export const selectBookingPackagePax = createSelector(
147
+ selectTravelersFormValues,
148
+ (formValues) => {
149
+ var pax: BookingPackagePax[] = [];
150
+
151
+ formValues?.adults.forEach((x) => {
152
+ const adultPax = buildPax(x, formValues?.mainBookerId);
153
+
154
+ if (adultPax.isMainBooker) {
155
+ adultPax.mobilePhone = formValues?.phone;
156
+ adultPax.email = formValues?.email;
157
+ }
158
+
159
+ pax.push(adultPax);
160
+ });
161
+
162
+ formValues?.children.forEach((x) => {
163
+ pax.push(buildPax(x));
164
+ });
165
+
166
+ return pax;
167
+ }
168
+ );
169
+
170
+ export const selectBookingAddress = createSelector(
171
+ selectTravelersFormValues,
172
+ selectBookingPackagePax,
173
+ (formValues, pax) => {
174
+ const mainBooker = pax.find((x) => x.isMainBooker);
175
+ if (!mainBooker) return undefined;
176
+
177
+ return {
178
+ name: `${mainBooker.firstName} ${mainBooker.lastName}`,
179
+ street: formValues?.street,
180
+ number: formValues?.houseNumber,
181
+ box: formValues?.box,
182
+ postalCode: formValues?.zipCode,
183
+ location: formValues?.place,
184
+ country: formValues?.country,
185
+ mobilePhone: formValues?.phone,
186
+ email: formValues?.email,
187
+ } as BookingPackageAddress;
188
+ }
189
+ );
190
+
191
+ export const selectBookingPackageRequest = createSelector(
192
+ selectOfficeId,
193
+ selectAgentId,
194
+ selectAgentAdressId,
195
+ (officeId, agentId, agentAdressId) => {
196
+ const agencyId =
197
+ (agentId ?? agentAdressId ?? 0) > 0 ? agentId ?? agentAdressId : null;
198
+
199
+ return {
200
+ officeId: officeId,
201
+ agentId: agencyId,
202
+ payload: null,
203
+ } as BookingPackageRequest<any>;
204
+ }
205
+ );
206
+
207
+ export const selectBookingPackageBookRequest = createSelector(
208
+ selectBookingPackageRequest,
209
+ selectBookingOptions,
210
+ selectBookingType,
211
+ selectBookingPackagePax,
212
+ selectBookingAddress,
213
+ selectPackageDetails,
214
+ selectCalculateDeposit,
215
+ selectAgentId,
216
+ selectGeneratePaymentUrl,
217
+ selectSkipPaymentWithAgent,
218
+ selectNotifications,
219
+ selectTagIds,
220
+ selectBookingRemarks,
221
+ selectVoucherCodes,
222
+ (
223
+ bookingPackageRequest: BookingPackageRequest<BookingPackageBookRequest>,
224
+ bookingOptions,
225
+ bookingType,
226
+ pax,
227
+ address,
228
+ packageDetails,
229
+ calculateDeposit,
230
+ agentId,
231
+ generatePaymentUrl,
232
+ skipPaymentWithAgent,
233
+ notifications,
234
+ tagIds,
235
+ remarks,
236
+ voucherCodes
237
+ ) => {
238
+ if (!packageDetails || pax?.length == 0) return null;
239
+
240
+ let returnPaymentUrl = false;
241
+
242
+ if (generatePaymentUrl && (!skipPaymentWithAgent || (agentId ?? 0) == 0)) {
243
+ returnPaymentUrl = true;
244
+ }
245
+
246
+ var entryStatus = 0;
247
+ var customEntryStatusId = undefined;
248
+
249
+ switch (bookingType) {
250
+ case "b2b":
251
+ if (bookingOptions.b2b.tagIds && bookingOptions.b2b.tagIds.length > 0) {
252
+ tagIds = tagIds?.concat(bookingOptions.b2b.tagIds);
253
+ }
254
+ if (bookingOptions.b2b.entryStatus) {
255
+ entryStatus = bookingOptions.b2b.entryStatus;
256
+ }
257
+ if (bookingOptions.b2b.customEntryStatusId) {
258
+ customEntryStatusId = bookingOptions.b2b.customEntryStatusId;
259
+ }
260
+ break;
261
+ case "b2b2c":
262
+ if (
263
+ bookingOptions.b2b2c.tagIds &&
264
+ bookingOptions.b2b2c.tagIds.length > 0
265
+ ) {
266
+ tagIds = tagIds?.concat(bookingOptions.b2b2c.tagIds);
267
+ }
268
+ if (bookingOptions.b2b2c.entryStatus) {
269
+ entryStatus = bookingOptions.b2b2c.entryStatus;
270
+ }
271
+ if (bookingOptions.b2b2c.customEntryStatusId) {
272
+ customEntryStatusId = bookingOptions.b2b2c.customEntryStatusId;
273
+ }
274
+ break;
275
+ default:
276
+ if (bookingOptions.b2c.tagIds && bookingOptions.b2c.tagIds.length > 0) {
277
+ tagIds = tagIds?.concat(bookingOptions.b2c.tagIds);
278
+ }
279
+ if (bookingOptions.b2c.entryStatus) {
280
+ entryStatus = bookingOptions.b2c.entryStatus;
281
+ }
282
+ if (bookingOptions.b2c.customEntryStatusId) {
283
+ customEntryStatusId = bookingOptions.b2c.customEntryStatusId;
284
+ }
285
+ break;
286
+ }
287
+
288
+ bookingPackageRequest.payload = {
289
+ package: packageDetails,
290
+ status: entryStatus,
291
+ customStatusId: customEntryStatusId,
292
+ address: address,
293
+ pax: pax,
294
+ nonTravelPax: [],
295
+ calculateDeposit: calculateDeposit,
296
+ returnPaymentUrl: returnPaymentUrl,
297
+ notifications: notifications,
298
+ tagIds: tagIds,
299
+ remarks: remarks,
300
+ voucherCodes: voucherCodes,
301
+ };
302
+
303
+ return bookingPackageRequest;
304
+ }
305
+ );
306
+
307
+ const buildPax = (traveler: Traveler, mainBookerId?: number) => {
308
+ return {
309
+ id: traveler.id,
310
+ gender: parseGender(traveler.gender),
311
+ firstName: traveler.firstName,
312
+ lastName: traveler.lastName,
313
+ dateOfBirth: traveler.birthDate,
314
+ isMainBooker: traveler.id == mainBookerId,
315
+ } as BookingPackagePax;
316
+ };
317
+
318
+ const parseGender = (gender: string): number => {
319
+ switch (gender) {
320
+ case "m":
321
+ return Gender.male;
322
+ case "f":
323
+ return Gender.female;
324
+ case "x":
325
+ default:
326
+ return Gender.other;
327
+ }
328
+ };