@qite/tide-booking-component 1.4.92 → 1.4.93

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 (591) hide show
  1. package/.prettierrc +9 -9
  2. package/.vs/ProjectSettings.json +3 -3
  3. package/.vs/VSWorkspaceState.json +5 -5
  4. package/README.md +24 -24
  5. package/build/build-cjs/index.js +29559 -48610
  6. package/build/build-cjs/src/booking-product/components/age-select.d.ts +3 -3
  7. package/build/build-cjs/src/booking-product/components/amount-input.d.ts +5 -5
  8. package/build/build-cjs/src/booking-product/components/date-range-picker/calendar-day.d.ts +8 -8
  9. package/build/build-cjs/src/booking-product/components/date-range-picker/calendar.d.ts +14 -14
  10. package/build/build-cjs/src/booking-product/components/date-range-picker/index.d.ts +19 -16
  11. package/build/build-cjs/src/booking-product/components/dates.d.ts +8 -8
  12. package/build/build-cjs/src/booking-product/components/footer.d.ts +5 -5
  13. package/build/build-cjs/src/booking-product/components/header.d.ts +6 -6
  14. package/build/build-cjs/src/booking-product/components/icon.d.ts +5 -5
  15. package/build/build-cjs/src/booking-product/components/list-view.d.ts +2 -2
  16. package/build/build-cjs/src/booking-product/components/product.d.ts +4 -4
  17. package/build/build-cjs/src/booking-product/components/rating.d.ts +1 -1
  18. package/build/build-cjs/src/booking-product/components/rooms.d.ts +4 -4
  19. package/build/build-cjs/src/booking-product/constants.d.ts +1 -1
  20. package/build/build-cjs/src/booking-product/index.d.ts +4 -4
  21. package/build/build-cjs/src/booking-product/settings-context.d.ts +2 -1
  22. package/build/build-cjs/src/booking-product/types.d.ts +21 -21
  23. package/build/build-cjs/src/booking-product/utils/api.d.ts +2 -11
  24. package/build/build-cjs/src/booking-product/utils/price.d.ts +1 -10
  25. package/build/build-cjs/src/booking-wizard/api-settings-slice.d.ts +2 -3
  26. package/build/build-cjs/src/booking-wizard/components/icon.d.ts +5 -5
  27. package/build/build-cjs/src/booking-wizard/components/labeled-input.d.ts +13 -13
  28. package/build/build-cjs/src/booking-wizard/components/labeled-select.d.ts +16 -16
  29. package/build/build-cjs/src/booking-wizard/components/message.d.ts +4 -4
  30. package/build/build-cjs/src/booking-wizard/components/multi-range-filter.d.ts +6 -6
  31. package/build/build-cjs/src/booking-wizard/components/phone-input.d.ts +11 -11
  32. package/build/build-cjs/src/booking-wizard/components/print-offer-button.d.ts +11 -11
  33. package/build/build-cjs/src/booking-wizard/components/product-card.d.ts +3 -3
  34. package/build/build-cjs/src/booking-wizard/components/step-indicator.d.ts +1 -1
  35. package/build/build-cjs/src/booking-wizard/components/step-route.d.ts +3 -3
  36. package/build/build-cjs/src/booking-wizard/features/booking/api.d.ts +7 -26
  37. package/build/build-cjs/src/booking-wizard/features/booking/booking-self-contained.d.ts +3 -3
  38. package/build/build-cjs/src/booking-wizard/features/booking/booking-slice.d.ts +42 -100
  39. package/build/build-cjs/src/booking-wizard/features/booking/booking.d.ts +3 -3
  40. package/build/build-cjs/src/booking-wizard/features/booking/constants.d.ts +1 -8
  41. package/build/build-cjs/src/booking-wizard/features/booking/selectors.d.ts +479 -641
  42. package/build/build-cjs/src/booking-wizard/features/confirmation/confirmation.d.ts +2 -1
  43. package/build/build-cjs/src/booking-wizard/features/error/error.d.ts +2 -1
  44. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-filter.d.ts +3 -3
  45. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-option-flight.d.ts +2 -2
  46. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-option.d.ts +4 -4
  47. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-utils.d.ts +2 -9
  48. package/build/build-cjs/src/booking-wizard/features/flight-options/index.d.ts +2 -1
  49. package/build/build-cjs/src/booking-wizard/features/price-details/price-details-api.d.ts +1 -6
  50. package/build/build-cjs/src/booking-wizard/features/price-details/price-details-slice.d.ts +9 -14
  51. package/build/build-cjs/src/booking-wizard/features/price-details/selectors.d.ts +287 -302
  52. package/build/build-cjs/src/booking-wizard/features/product-options/none-option.d.ts +3 -3
  53. package/build/build-cjs/src/booking-wizard/features/product-options/option-booking-airline-group.d.ts +2 -2
  54. package/build/build-cjs/src/booking-wizard/features/product-options/option-booking-group.d.ts +6 -6
  55. package/build/build-cjs/src/booking-wizard/features/product-options/option-item.d.ts +5 -5
  56. package/build/build-cjs/src/booking-wizard/features/product-options/option-pax-card.d.ts +4 -4
  57. package/build/build-cjs/src/booking-wizard/features/product-options/option-pax-group.d.ts +7 -7
  58. package/build/build-cjs/src/booking-wizard/features/product-options/option-room.d.ts +5 -5
  59. package/build/build-cjs/src/booking-wizard/features/product-options/option-unit-group.d.ts +7 -7
  60. package/build/build-cjs/src/booking-wizard/features/product-options/option-units-card.d.ts +3 -3
  61. package/build/build-cjs/src/booking-wizard/features/product-options/options-form.d.ts +2 -1
  62. package/build/build-cjs/src/booking-wizard/features/room-options/index.d.ts +2 -1
  63. package/build/build-cjs/src/booking-wizard/features/room-options/room-utils.d.ts +6 -19
  64. package/build/build-cjs/src/booking-wizard/features/room-options/room.d.ts +6 -6
  65. package/build/build-cjs/src/booking-wizard/features/room-options/traveler-rooms.d.ts +3 -3
  66. package/build/build-cjs/src/booking-wizard/features/sidebar/index.d.ts +2 -2
  67. package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar-flight.d.ts +2 -2
  68. package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar-util.d.ts +2 -4
  69. package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar.d.ts +23 -23
  70. package/build/build-cjs/src/booking-wizard/features/summary/summary-booking-option-pax.d.ts +1 -1
  71. package/build/build-cjs/src/booking-wizard/features/summary/summary-booking-option-unit.d.ts +1 -1
  72. package/build/build-cjs/src/booking-wizard/features/summary/summary-flight.d.ts +2 -2
  73. package/build/build-cjs/src/booking-wizard/features/summary/summary-per-booking-option-group.d.ts +1 -1
  74. package/build/build-cjs/src/booking-wizard/features/summary/summary-per-pax-option-group.d.ts +1 -1
  75. package/build/build-cjs/src/booking-wizard/features/summary/summary-per-unit-option-group.d.ts +1 -1
  76. package/build/build-cjs/src/booking-wizard/features/summary/summary-slice.d.ts +3 -3
  77. package/build/build-cjs/src/booking-wizard/features/summary/summary.d.ts +2 -1
  78. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +75 -75
  79. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form-util.d.ts +4 -4
  80. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form.d.ts +2 -1
  81. package/build/build-cjs/src/booking-wizard/features/travelers-form/type-ahead-input.d.ts +11 -11
  82. package/build/build-cjs/src/booking-wizard/features/travelers-form/validate-form.d.ts +1 -8
  83. package/build/build-cjs/src/booking-wizard/index.d.ts +6 -6
  84. package/build/build-cjs/src/booking-wizard/settings-context.d.ts +2 -1
  85. package/build/build-cjs/src/booking-wizard/store.d.ts +22 -40
  86. package/build/build-cjs/src/booking-wizard/types.d.ts +239 -239
  87. package/build/build-cjs/src/booking-wizard/use-offer-printer.d.ts +8 -8
  88. package/build/build-cjs/src/content/components/LanguageSwitcher.d.ts +5 -5
  89. package/build/build-cjs/src/content/components/accordion.d.ts +4 -4
  90. package/build/build-cjs/src/content/components/breadcrumb.d.ts +7 -7
  91. package/build/build-cjs/src/content/components/faq.d.ts +4 -4
  92. package/build/build-cjs/src/content/components/gallery.d.ts +6 -6
  93. package/build/build-cjs/src/content/components/icon.d.ts +5 -5
  94. package/build/build-cjs/src/content/components/image-with-text.d.ts +18 -18
  95. package/build/build-cjs/src/content/components/slider.d.ts +5 -5
  96. package/build/build-cjs/src/content/featured-trips/types.d.ts +8 -8
  97. package/build/build-cjs/src/content/features/content-page/content-page-self-contained.d.ts +1 -1
  98. package/build/build-cjs/src/content/footer/types.d.ts +17 -17
  99. package/build/build-cjs/src/content/header/types.d.ts +20 -23
  100. package/build/build-cjs/src/content/image-card-grid/types.d.ts +8 -8
  101. package/build/build-cjs/src/content/image-with-text-section/types.d.ts +15 -15
  102. package/build/build-cjs/src/content/login/login-services.d.ts +1 -6
  103. package/build/build-cjs/src/content/login/types.d.ts +19 -19
  104. package/build/build-cjs/src/content/navbar/placeholderData.d.ts +2 -2
  105. package/build/build-cjs/src/content/navbar/types.d.ts +22 -22
  106. package/build/build-cjs/src/index.d.ts +1 -17
  107. package/build/build-cjs/src/qsm/components/date-range-picker/calendar-day.d.ts +7 -7
  108. package/build/build-cjs/src/qsm/components/date-range-picker/calendar.d.ts +18 -18
  109. package/build/build-cjs/src/qsm/components/date-range-picker/index.d.ts +5 -5
  110. package/build/build-cjs/src/qsm/components/double-search-input-group/index.d.ts +2 -2
  111. package/build/build-cjs/src/qsm/components/icon.d.ts +5 -5
  112. package/build/build-cjs/src/qsm/components/item-picker/index.d.ts +7 -7
  113. package/build/build-cjs/src/qsm/components/search-input/index.d.ts +9 -9
  114. package/build/build-cjs/src/qsm/components/search-input-group/index.d.ts +7 -7
  115. package/build/build-cjs/src/qsm/index.d.ts +1 -1
  116. package/build/build-cjs/src/qsm/store/qsm-slice.d.ts +58 -110
  117. package/build/build-cjs/src/qsm/store/qsm-store.d.ts +7 -20
  118. package/build/build-cjs/src/qsm/types.d.ts +59 -59
  119. package/build/build-cjs/src/search-results/components/filters/filters.d.ts +5 -5
  120. package/build/build-cjs/src/search-results/components/filters/flight-filters.d.ts +3 -3
  121. package/build/build-cjs/src/search-results/components/flight/flight-banner.d.ts +2 -2
  122. package/build/build-cjs/src/search-results/components/flight/flight-card.d.ts +1 -1
  123. package/build/build-cjs/src/search-results/components/flight/flight-leg.d.ts +1 -1
  124. package/build/build-cjs/src/search-results/components/flight/flight-path.d.ts +1 -1
  125. package/build/build-cjs/src/search-results/components/flight/flight-results.d.ts +2 -2
  126. package/build/build-cjs/src/search-results/components/flight/flight-search-context/index.d.ts +29 -29
  127. package/build/build-cjs/src/search-results/components/flight/flight-selection/independent-flight-option.d.ts +5 -5
  128. package/build/build-cjs/src/search-results/components/flight/flight-selection/independent-flight-selection.d.ts +1 -1
  129. package/build/build-cjs/src/search-results/components/flight/flight-selection/index.d.ts +2 -2
  130. package/build/build-cjs/src/search-results/components/flight/flight-selection/paired-flight-option.d.ts +1 -1
  131. package/build/build-cjs/src/search-results/components/flight/flight-selection/paired-flight-selection.d.ts +1 -1
  132. package/build/build-cjs/src/search-results/components/group-tour/group-tour-card.d.ts +3 -3
  133. package/build/build-cjs/src/search-results/components/group-tour/group-tour-results.d.ts +1 -1
  134. package/build/build-cjs/src/search-results/components/hotel/hotel-accommodation-results.d.ts +1 -1
  135. package/build/build-cjs/src/search-results/components/hotel/hotel-card.d.ts +2 -2
  136. package/build/build-cjs/src/search-results/components/icon.d.ts +6 -6
  137. package/build/build-cjs/src/search-results/components/item-picker/index.d.ts +8 -8
  138. package/build/build-cjs/src/search-results/components/itinerary/index.d.ts +3 -3
  139. package/build/build-cjs/src/search-results/components/multi-range-filter.d.ts +6 -6
  140. package/build/build-cjs/src/search-results/components/round-trip/round-trip-results.d.ts +2 -1
  141. package/build/build-cjs/src/search-results/components/search-results-container/flight-search-results.d.ts +1 -1
  142. package/build/build-cjs/src/search-results/components/tab-views/index.d.ts +2 -1
  143. package/build/build-cjs/src/search-results/features/flights/flight-search-results-self-contained.d.ts +2 -1
  144. package/build/build-cjs/src/search-results/features/hotels/hotel-flight-search-results-self-contained.d.ts +2 -1
  145. package/build/build-cjs/src/search-results/features/hotels/hotel-search-results-self-contained.d.ts +2 -1
  146. package/build/build-cjs/src/search-results/features/roundtrips/roundtrip-search-results-self-contained.d.ts +2 -1
  147. package/build/build-cjs/src/search-results/index.d.ts +1 -1
  148. package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +26 -63
  149. package/build/build-cjs/src/search-results/store/search-results-store.d.ts +7 -20
  150. package/build/build-cjs/src/search-results/types.d.ts +104 -104
  151. package/build/build-cjs/src/search-results/utils/flight-utils.d.ts +1 -6
  152. package/build/build-cjs/src/search-results/utils/search-results-utils.d.ts +2 -10
  153. package/build/build-cjs/src/shared/components/flyin/accommodation-flyin.d.ts +3 -3
  154. package/build/build-cjs/src/shared/components/flyin/flights-flyin.d.ts +2 -2
  155. package/build/build-cjs/src/shared/components/flyin/flyin.d.ts +7 -7
  156. package/build/build-cjs/src/shared/components/flyin/group-tour-flyin.d.ts +3 -3
  157. package/build/build-cjs/src/shared/components/icon.d.ts +5 -5
  158. package/build/build-cjs/src/shared/components/loader.d.ts +1 -1
  159. package/build/build-cjs/src/shared/types.d.ts +9 -9
  160. package/build/build-cjs/src/shared/utils/localization-util.d.ts +395 -395
  161. package/build/build-esm/index.js +29536 -48364
  162. package/build/build-esm/src/booking-product/components/age-select.d.ts +3 -3
  163. package/build/build-esm/src/booking-product/components/amount-input.d.ts +5 -5
  164. package/build/build-esm/src/booking-product/components/date-range-picker/calendar-day.d.ts +8 -8
  165. package/build/build-esm/src/booking-product/components/date-range-picker/calendar.d.ts +14 -14
  166. package/build/build-esm/src/booking-product/components/date-range-picker/index.d.ts +19 -16
  167. package/build/build-esm/src/booking-product/components/dates.d.ts +8 -8
  168. package/build/build-esm/src/booking-product/components/footer.d.ts +5 -5
  169. package/build/build-esm/src/booking-product/components/header.d.ts +6 -6
  170. package/build/build-esm/src/booking-product/components/icon.d.ts +5 -5
  171. package/build/build-esm/src/booking-product/components/list-view.d.ts +2 -2
  172. package/build/build-esm/src/booking-product/components/product.d.ts +4 -4
  173. package/build/build-esm/src/booking-product/components/rating.d.ts +1 -1
  174. package/build/build-esm/src/booking-product/components/rooms.d.ts +4 -4
  175. package/build/build-esm/src/booking-product/constants.d.ts +1 -1
  176. package/build/build-esm/src/booking-product/index.d.ts +4 -4
  177. package/build/build-esm/src/booking-product/settings-context.d.ts +2 -1
  178. package/build/build-esm/src/booking-product/types.d.ts +21 -21
  179. package/build/build-esm/src/booking-product/utils/api.d.ts +2 -11
  180. package/build/build-esm/src/booking-product/utils/price.d.ts +1 -10
  181. package/build/build-esm/src/booking-wizard/api-settings-slice.d.ts +2 -3
  182. package/build/build-esm/src/booking-wizard/components/icon.d.ts +5 -5
  183. package/build/build-esm/src/booking-wizard/components/labeled-input.d.ts +13 -13
  184. package/build/build-esm/src/booking-wizard/components/labeled-select.d.ts +16 -16
  185. package/build/build-esm/src/booking-wizard/components/message.d.ts +4 -4
  186. package/build/build-esm/src/booking-wizard/components/multi-range-filter.d.ts +6 -6
  187. package/build/build-esm/src/booking-wizard/components/phone-input.d.ts +11 -11
  188. package/build/build-esm/src/booking-wizard/components/print-offer-button.d.ts +11 -11
  189. package/build/build-esm/src/booking-wizard/components/product-card.d.ts +3 -3
  190. package/build/build-esm/src/booking-wizard/components/step-indicator.d.ts +1 -1
  191. package/build/build-esm/src/booking-wizard/components/step-route.d.ts +3 -3
  192. package/build/build-esm/src/booking-wizard/features/booking/api.d.ts +7 -26
  193. package/build/build-esm/src/booking-wizard/features/booking/booking-self-contained.d.ts +3 -3
  194. package/build/build-esm/src/booking-wizard/features/booking/booking-slice.d.ts +42 -100
  195. package/build/build-esm/src/booking-wizard/features/booking/booking.d.ts +3 -3
  196. package/build/build-esm/src/booking-wizard/features/booking/constants.d.ts +1 -8
  197. package/build/build-esm/src/booking-wizard/features/booking/selectors.d.ts +479 -641
  198. package/build/build-esm/src/booking-wizard/features/confirmation/confirmation.d.ts +2 -1
  199. package/build/build-esm/src/booking-wizard/features/error/error.d.ts +2 -1
  200. package/build/build-esm/src/booking-wizard/features/flight-options/flight-filter.d.ts +3 -3
  201. package/build/build-esm/src/booking-wizard/features/flight-options/flight-option-flight.d.ts +2 -2
  202. package/build/build-esm/src/booking-wizard/features/flight-options/flight-option.d.ts +4 -4
  203. package/build/build-esm/src/booking-wizard/features/flight-options/flight-utils.d.ts +2 -9
  204. package/build/build-esm/src/booking-wizard/features/flight-options/index.d.ts +2 -1
  205. package/build/build-esm/src/booking-wizard/features/price-details/price-details-api.d.ts +1 -6
  206. package/build/build-esm/src/booking-wizard/features/price-details/price-details-slice.d.ts +9 -14
  207. package/build/build-esm/src/booking-wizard/features/price-details/selectors.d.ts +287 -302
  208. package/build/build-esm/src/booking-wizard/features/product-options/none-option.d.ts +3 -3
  209. package/build/build-esm/src/booking-wizard/features/product-options/option-booking-airline-group.d.ts +2 -2
  210. package/build/build-esm/src/booking-wizard/features/product-options/option-booking-group.d.ts +6 -6
  211. package/build/build-esm/src/booking-wizard/features/product-options/option-item.d.ts +5 -5
  212. package/build/build-esm/src/booking-wizard/features/product-options/option-pax-card.d.ts +4 -4
  213. package/build/build-esm/src/booking-wizard/features/product-options/option-pax-group.d.ts +7 -7
  214. package/build/build-esm/src/booking-wizard/features/product-options/option-room.d.ts +5 -5
  215. package/build/build-esm/src/booking-wizard/features/product-options/option-unit-group.d.ts +7 -7
  216. package/build/build-esm/src/booking-wizard/features/product-options/option-units-card.d.ts +3 -3
  217. package/build/build-esm/src/booking-wizard/features/product-options/options-form.d.ts +2 -1
  218. package/build/build-esm/src/booking-wizard/features/room-options/index.d.ts +2 -1
  219. package/build/build-esm/src/booking-wizard/features/room-options/room-utils.d.ts +6 -19
  220. package/build/build-esm/src/booking-wizard/features/room-options/room.d.ts +6 -6
  221. package/build/build-esm/src/booking-wizard/features/room-options/traveler-rooms.d.ts +3 -3
  222. package/build/build-esm/src/booking-wizard/features/sidebar/index.d.ts +2 -2
  223. package/build/build-esm/src/booking-wizard/features/sidebar/sidebar-flight.d.ts +2 -2
  224. package/build/build-esm/src/booking-wizard/features/sidebar/sidebar-util.d.ts +2 -4
  225. package/build/build-esm/src/booking-wizard/features/sidebar/sidebar.d.ts +23 -23
  226. package/build/build-esm/src/booking-wizard/features/summary/summary-booking-option-pax.d.ts +1 -1
  227. package/build/build-esm/src/booking-wizard/features/summary/summary-booking-option-unit.d.ts +1 -1
  228. package/build/build-esm/src/booking-wizard/features/summary/summary-flight.d.ts +2 -2
  229. package/build/build-esm/src/booking-wizard/features/summary/summary-per-booking-option-group.d.ts +1 -1
  230. package/build/build-esm/src/booking-wizard/features/summary/summary-per-pax-option-group.d.ts +1 -1
  231. package/build/build-esm/src/booking-wizard/features/summary/summary-per-unit-option-group.d.ts +1 -1
  232. package/build/build-esm/src/booking-wizard/features/summary/summary-slice.d.ts +3 -3
  233. package/build/build-esm/src/booking-wizard/features/summary/summary.d.ts +2 -1
  234. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +75 -75
  235. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form-util.d.ts +4 -4
  236. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form.d.ts +2 -1
  237. package/build/build-esm/src/booking-wizard/features/travelers-form/type-ahead-input.d.ts +11 -11
  238. package/build/build-esm/src/booking-wizard/features/travelers-form/validate-form.d.ts +1 -8
  239. package/build/build-esm/src/booking-wizard/index.d.ts +6 -6
  240. package/build/build-esm/src/booking-wizard/settings-context.d.ts +2 -1
  241. package/build/build-esm/src/booking-wizard/store.d.ts +22 -40
  242. package/build/build-esm/src/booking-wizard/types.d.ts +239 -239
  243. package/build/build-esm/src/booking-wizard/use-offer-printer.d.ts +8 -8
  244. package/build/build-esm/src/content/components/LanguageSwitcher.d.ts +5 -5
  245. package/build/build-esm/src/content/components/accordion.d.ts +4 -4
  246. package/build/build-esm/src/content/components/breadcrumb.d.ts +7 -7
  247. package/build/build-esm/src/content/components/faq.d.ts +4 -4
  248. package/build/build-esm/src/content/components/gallery.d.ts +6 -6
  249. package/build/build-esm/src/content/components/icon.d.ts +5 -5
  250. package/build/build-esm/src/content/components/image-with-text.d.ts +18 -18
  251. package/build/build-esm/src/content/components/slider.d.ts +5 -5
  252. package/build/build-esm/src/content/featured-trips/types.d.ts +8 -8
  253. package/build/build-esm/src/content/features/content-page/content-page-self-contained.d.ts +1 -1
  254. package/build/build-esm/src/content/footer/types.d.ts +17 -17
  255. package/build/build-esm/src/content/header/types.d.ts +20 -23
  256. package/build/build-esm/src/content/image-card-grid/types.d.ts +8 -8
  257. package/build/build-esm/src/content/image-with-text-section/types.d.ts +15 -15
  258. package/build/build-esm/src/content/login/login-services.d.ts +1 -6
  259. package/build/build-esm/src/content/login/types.d.ts +19 -19
  260. package/build/build-esm/src/content/navbar/placeholderData.d.ts +2 -2
  261. package/build/build-esm/src/content/navbar/types.d.ts +22 -22
  262. package/build/build-esm/src/index.d.ts +1 -17
  263. package/build/build-esm/src/qsm/components/date-range-picker/calendar-day.d.ts +7 -7
  264. package/build/build-esm/src/qsm/components/date-range-picker/calendar.d.ts +18 -18
  265. package/build/build-esm/src/qsm/components/date-range-picker/index.d.ts +5 -5
  266. package/build/build-esm/src/qsm/components/double-search-input-group/index.d.ts +2 -2
  267. package/build/build-esm/src/qsm/components/icon.d.ts +5 -5
  268. package/build/build-esm/src/qsm/components/item-picker/index.d.ts +7 -7
  269. package/build/build-esm/src/qsm/components/search-input/index.d.ts +9 -9
  270. package/build/build-esm/src/qsm/components/search-input-group/index.d.ts +7 -7
  271. package/build/build-esm/src/qsm/index.d.ts +1 -1
  272. package/build/build-esm/src/qsm/store/qsm-slice.d.ts +58 -110
  273. package/build/build-esm/src/qsm/store/qsm-store.d.ts +7 -20
  274. package/build/build-esm/src/qsm/types.d.ts +59 -59
  275. package/build/build-esm/src/search-results/components/filters/filters.d.ts +5 -5
  276. package/build/build-esm/src/search-results/components/filters/flight-filters.d.ts +3 -3
  277. package/build/build-esm/src/search-results/components/flight/flight-banner.d.ts +2 -2
  278. package/build/build-esm/src/search-results/components/flight/flight-card.d.ts +1 -1
  279. package/build/build-esm/src/search-results/components/flight/flight-leg.d.ts +1 -1
  280. package/build/build-esm/src/search-results/components/flight/flight-path.d.ts +1 -1
  281. package/build/build-esm/src/search-results/components/flight/flight-results.d.ts +2 -2
  282. package/build/build-esm/src/search-results/components/flight/flight-search-context/index.d.ts +29 -29
  283. package/build/build-esm/src/search-results/components/flight/flight-selection/independent-flight-option.d.ts +5 -5
  284. package/build/build-esm/src/search-results/components/flight/flight-selection/independent-flight-selection.d.ts +1 -1
  285. package/build/build-esm/src/search-results/components/flight/flight-selection/index.d.ts +2 -2
  286. package/build/build-esm/src/search-results/components/flight/flight-selection/paired-flight-option.d.ts +1 -1
  287. package/build/build-esm/src/search-results/components/flight/flight-selection/paired-flight-selection.d.ts +1 -1
  288. package/build/build-esm/src/search-results/components/group-tour/group-tour-card.d.ts +3 -3
  289. package/build/build-esm/src/search-results/components/group-tour/group-tour-results.d.ts +1 -1
  290. package/build/build-esm/src/search-results/components/hotel/hotel-accommodation-results.d.ts +1 -1
  291. package/build/build-esm/src/search-results/components/hotel/hotel-card.d.ts +2 -2
  292. package/build/build-esm/src/search-results/components/icon.d.ts +6 -6
  293. package/build/build-esm/src/search-results/components/item-picker/index.d.ts +8 -8
  294. package/build/build-esm/src/search-results/components/itinerary/index.d.ts +3 -3
  295. package/build/build-esm/src/search-results/components/multi-range-filter.d.ts +6 -6
  296. package/build/build-esm/src/search-results/components/round-trip/round-trip-results.d.ts +2 -1
  297. package/build/build-esm/src/search-results/components/search-results-container/flight-search-results.d.ts +1 -1
  298. package/build/build-esm/src/search-results/components/tab-views/index.d.ts +2 -1
  299. package/build/build-esm/src/search-results/features/flights/flight-search-results-self-contained.d.ts +2 -1
  300. package/build/build-esm/src/search-results/features/hotels/hotel-flight-search-results-self-contained.d.ts +2 -1
  301. package/build/build-esm/src/search-results/features/hotels/hotel-search-results-self-contained.d.ts +2 -1
  302. package/build/build-esm/src/search-results/features/roundtrips/roundtrip-search-results-self-contained.d.ts +2 -1
  303. package/build/build-esm/src/search-results/index.d.ts +1 -1
  304. package/build/build-esm/src/search-results/store/search-results-slice.d.ts +26 -63
  305. package/build/build-esm/src/search-results/store/search-results-store.d.ts +7 -20
  306. package/build/build-esm/src/search-results/types.d.ts +104 -104
  307. package/build/build-esm/src/search-results/utils/flight-utils.d.ts +1 -6
  308. package/build/build-esm/src/search-results/utils/search-results-utils.d.ts +2 -10
  309. package/build/build-esm/src/shared/components/flyin/accommodation-flyin.d.ts +3 -3
  310. package/build/build-esm/src/shared/components/flyin/flights-flyin.d.ts +2 -2
  311. package/build/build-esm/src/shared/components/flyin/flyin.d.ts +7 -7
  312. package/build/build-esm/src/shared/components/flyin/group-tour-flyin.d.ts +3 -3
  313. package/build/build-esm/src/shared/components/icon.d.ts +5 -5
  314. package/build/build-esm/src/shared/components/loader.d.ts +1 -1
  315. package/build/build-esm/src/shared/types.d.ts +9 -9
  316. package/build/build-esm/src/shared/utils/localization-util.d.ts +395 -395
  317. package/package.json +1 -1
  318. package/rollup.config.js +16 -16
  319. package/src/booking-product/components/age-select.tsx +35 -35
  320. package/src/booking-product/components/amount-input.tsx +51 -51
  321. package/src/booking-product/components/date-range-picker/calendar-day.tsx +46 -46
  322. package/src/booking-product/components/date-range-picker/calendar.tsx +155 -155
  323. package/src/booking-product/components/date-range-picker/index.tsx +185 -185
  324. package/src/booking-product/components/dates.tsx +153 -153
  325. package/src/booking-product/components/footer.tsx +54 -54
  326. package/src/booking-product/components/header.tsx +57 -57
  327. package/src/booking-product/components/icon.tsx +200 -200
  328. package/src/booking-product/components/list-view.tsx +54 -54
  329. package/src/booking-product/components/product.tsx +379 -379
  330. package/src/booking-product/components/rating.tsx +21 -21
  331. package/src/booking-product/components/rooms.tsx +171 -171
  332. package/src/booking-product/constants.ts +1 -1
  333. package/src/booking-product/index.tsx +21 -21
  334. package/src/booking-product/settings-context.ts +16 -16
  335. package/src/booking-product/types.ts +30 -30
  336. package/src/booking-product/utils/api.ts +26 -26
  337. package/src/booking-product/utils/price.ts +28 -28
  338. package/src/booking-wizard/api-settings-slice.ts +24 -24
  339. package/src/booking-wizard/components/icon.tsx +398 -398
  340. package/src/booking-wizard/components/labeled-input.tsx +56 -56
  341. package/src/booking-wizard/components/labeled-select.tsx +54 -54
  342. package/src/booking-wizard/components/message.tsx +21 -21
  343. package/src/booking-wizard/components/multi-range-filter.tsx +99 -99
  344. package/src/booking-wizard/components/phone-input.tsx +146 -146
  345. package/src/booking-wizard/components/print-offer-button.tsx +53 -53
  346. package/src/booking-wizard/components/product-card.tsx +23 -23
  347. package/src/booking-wizard/components/step-indicator.tsx +57 -57
  348. package/src/booking-wizard/components/step-route.tsx +26 -26
  349. package/src/booking-wizard/declarations.d.ts +4 -4
  350. package/src/booking-wizard/features/booking/api.ts +44 -44
  351. package/src/booking-wizard/features/booking/booking-self-contained.tsx +303 -303
  352. package/src/booking-wizard/features/booking/booking-slice.ts +625 -625
  353. package/src/booking-wizard/features/booking/booking.tsx +327 -326
  354. package/src/booking-wizard/features/booking/constants.ts +16 -16
  355. package/src/booking-wizard/features/booking/selectors.ts +406 -406
  356. package/src/booking-wizard/features/confirmation/confirmation.tsx +90 -90
  357. package/src/booking-wizard/features/error/error.tsx +71 -71
  358. package/src/booking-wizard/features/flight-options/flight-filter.tsx +371 -371
  359. package/src/booking-wizard/features/flight-options/flight-option-flight.tsx +354 -354
  360. package/src/booking-wizard/features/flight-options/flight-option-modal.tsx +211 -211
  361. package/src/booking-wizard/features/flight-options/flight-option.tsx +57 -57
  362. package/src/booking-wizard/features/flight-options/flight-utils.ts +423 -423
  363. package/src/booking-wizard/features/flight-options/index.tsx +166 -166
  364. package/src/booking-wizard/features/price-details/price-details-api.ts +20 -20
  365. package/src/booking-wizard/features/price-details/price-details-slice.ts +77 -77
  366. package/src/booking-wizard/features/price-details/selectors.ts +117 -117
  367. package/src/booking-wizard/features/price-details/util.ts +115 -115
  368. package/src/booking-wizard/features/product-options/no-options.tsx +18 -18
  369. package/src/booking-wizard/features/product-options/none-option.tsx +73 -73
  370. package/src/booking-wizard/features/product-options/option-booking-airline-group.tsx +53 -53
  371. package/src/booking-wizard/features/product-options/option-booking-group.tsx +152 -152
  372. package/src/booking-wizard/features/product-options/option-item.tsx +236 -236
  373. package/src/booking-wizard/features/product-options/option-pax-card.tsx +159 -159
  374. package/src/booking-wizard/features/product-options/option-pax-group.tsx +122 -122
  375. package/src/booking-wizard/features/product-options/option-room.tsx +226 -226
  376. package/src/booking-wizard/features/product-options/option-unit-group.tsx +138 -138
  377. package/src/booking-wizard/features/product-options/option-units-card.tsx +148 -148
  378. package/src/booking-wizard/features/product-options/options-form.tsx +382 -382
  379. package/src/booking-wizard/features/room-options/index.tsx +132 -132
  380. package/src/booking-wizard/features/room-options/room-utils.ts +154 -154
  381. package/src/booking-wizard/features/room-options/room.tsx +123 -123
  382. package/src/booking-wizard/features/room-options/traveler-rooms.tsx +64 -64
  383. package/src/booking-wizard/features/sidebar/index.tsx +81 -81
  384. package/src/booking-wizard/features/sidebar/sidebar-flight.tsx +66 -66
  385. package/src/booking-wizard/features/sidebar/sidebar-util.ts +147 -147
  386. package/src/booking-wizard/features/sidebar/sidebar.tsx +316 -316
  387. package/src/booking-wizard/features/summary/summary-booking-option-pax.tsx +23 -23
  388. package/src/booking-wizard/features/summary/summary-booking-option-unit.tsx +23 -23
  389. package/src/booking-wizard/features/summary/summary-flight.tsx +36 -36
  390. package/src/booking-wizard/features/summary/summary-per-booking-option-group.tsx +60 -60
  391. package/src/booking-wizard/features/summary/summary-per-pax-option-group.tsx +56 -56
  392. package/src/booking-wizard/features/summary/summary-per-unit-option-group.tsx +58 -58
  393. package/src/booking-wizard/features/summary/summary-slice.ts +27 -27
  394. package/src/booking-wizard/features/summary/summary.tsx +562 -562
  395. package/src/booking-wizard/features/travelers-form/controls/gender-control.tsx +60 -60
  396. package/src/booking-wizard/features/travelers-form/travelers-form-slice.ts +157 -157
  397. package/src/booking-wizard/features/travelers-form/travelers-form-util.ts +10 -10
  398. package/src/booking-wizard/features/travelers-form/travelers-form.tsx +1101 -1101
  399. package/src/booking-wizard/features/travelers-form/type-ahead-input.tsx +85 -85
  400. package/src/booking-wizard/features/travelers-form/validate-form.ts +178 -178
  401. package/src/booking-wizard/index.tsx +27 -27
  402. package/src/booking-wizard/settings-context.ts +64 -64
  403. package/src/booking-wizard/store.ts +26 -26
  404. package/src/booking-wizard/types.ts +331 -331
  405. package/src/booking-wizard/use-offer-printer.ts +108 -108
  406. package/src/content/components/LanguageSwitcher.tsx +158 -158
  407. package/src/content/components/accordion.tsx +30 -30
  408. package/src/content/components/breadcrumb.tsx +67 -67
  409. package/src/content/components/contact.tsx +211 -211
  410. package/src/content/components/faq.tsx +42 -42
  411. package/src/content/components/gallery.tsx +153 -153
  412. package/src/content/components/icon.tsx +695 -695
  413. package/src/content/components/image-with-text.tsx +120 -120
  414. package/src/content/components/login.tsx +162 -162
  415. package/src/content/components/personal-contact-form.tsx +809 -809
  416. package/src/content/components/slider.tsx +237 -237
  417. package/src/content/featured-trips/featured-trip-card.tsx +48 -48
  418. package/src/content/featured-trips/index.tsx +19 -19
  419. package/src/content/featured-trips/types.ts +13 -13
  420. package/src/content/features/content-page/content-page-self-contained.tsx +895 -895
  421. package/src/content/footer/index.tsx +159 -159
  422. package/src/content/footer/types.ts +36 -36
  423. package/src/content/header/index.tsx +43 -43
  424. package/src/content/header/types.ts +26 -26
  425. package/src/content/image-card-grid/index.tsx +34 -34
  426. package/src/content/image-card-grid/types.ts +13 -13
  427. package/src/content/image-with-text-section/card.tsx +58 -58
  428. package/src/content/image-with-text-section/index.tsx +22 -22
  429. package/src/content/image-with-text-section/types.ts +20 -20
  430. package/src/content/login/confirm-component.tsx +149 -149
  431. package/src/content/login/index.tsx +70 -70
  432. package/src/content/login/login-component.tsx +159 -159
  433. package/src/content/login/login-services.ts +109 -109
  434. package/src/content/login/reset-password-component.tsx +191 -191
  435. package/src/content/login/types.ts +29 -29
  436. package/src/content/navbar/index.tsx +354 -354
  437. package/src/content/navbar/placeholderData.tsx +173 -173
  438. package/src/content/navbar/types.ts +43 -43
  439. package/src/index.ts +44 -44
  440. package/src/qsm/components/QSMContainer/qsm-container.tsx +512 -512
  441. package/src/qsm/components/date-picker/index.tsx +152 -152
  442. package/src/qsm/components/date-range-picker/calendar-day.tsx +49 -49
  443. package/src/qsm/components/date-range-picker/calendar.tsx +211 -211
  444. package/src/qsm/components/date-range-picker/index.tsx +404 -404
  445. package/src/qsm/components/double-search-input-group/index.tsx +78 -78
  446. package/src/qsm/components/icon.tsx +354 -354
  447. package/src/qsm/components/item-picker/index.tsx +69 -69
  448. package/src/qsm/components/mobile-filter-modal/index.tsx +307 -307
  449. package/src/qsm/components/search-input/index.tsx +91 -91
  450. package/src/qsm/components/search-input-group/index.tsx +199 -199
  451. package/src/qsm/components/travel-class-picker/index.tsx +28 -28
  452. package/src/qsm/components/travel-input/index.tsx +243 -243
  453. package/src/qsm/components/travel-input-group/index.tsx +114 -114
  454. package/src/qsm/components/travel-nationality-picker/index.tsx +28 -28
  455. package/src/qsm/components/travel-type-picker/index.tsx +28 -28
  456. package/src/qsm/index.tsx +26 -26
  457. package/src/qsm/qsm-configuration-context.ts +31 -31
  458. package/src/qsm/store/qsm-slice.ts +275 -275
  459. package/src/qsm/store/qsm-store.ts +13 -13
  460. package/src/qsm/types.ts +110 -110
  461. package/src/search-results/components/filters/filters.tsx +230 -230
  462. package/src/search-results/components/filters/flight-filters.tsx +671 -671
  463. package/src/search-results/components/flight/flight-banner.tsx +35 -35
  464. package/src/search-results/components/flight/flight-card.tsx +38 -38
  465. package/src/search-results/components/flight/flight-leg.tsx +61 -61
  466. package/src/search-results/components/flight/flight-path.tsx +23 -23
  467. package/src/search-results/components/flight/flight-results.tsx +208 -208
  468. package/src/search-results/components/flight/flight-search-context/index.tsx +628 -628
  469. package/src/search-results/components/flight/flight-selection/independent-flight-option.tsx +147 -147
  470. package/src/search-results/components/flight/flight-selection/independent-flight-selection.tsx +172 -172
  471. package/src/search-results/components/flight/flight-selection/index.tsx +19 -19
  472. package/src/search-results/components/flight/flight-selection/paired-flight-option.tsx +255 -255
  473. package/src/search-results/components/flight/flight-selection/paired-flight-selection.tsx +38 -38
  474. package/src/search-results/components/group-tour/group-tour-card.tsx +105 -105
  475. package/src/search-results/components/group-tour/group-tour-results.tsx +62 -62
  476. package/src/search-results/components/hotel/hotel-accommodation-results.tsx +176 -176
  477. package/src/search-results/components/hotel/hotel-card.tsx +113 -113
  478. package/src/search-results/components/icon.tsx +680 -680
  479. package/src/search-results/components/item-picker/index.tsx +81 -81
  480. package/src/search-results/components/itinerary/index.tsx +310 -310
  481. package/src/search-results/components/multi-range-filter.tsx +104 -104
  482. package/src/search-results/components/round-trip/round-trip-results.tsx +199 -199
  483. package/src/search-results/components/search-results-container/flight-search-results.tsx +137 -137
  484. package/src/search-results/components/search-results-container/search-results-container.tsx +893 -893
  485. package/src/search-results/components/spinner/spinner.tsx +16 -16
  486. package/src/search-results/components/tab-views/index.tsx +53 -53
  487. package/src/search-results/features/flights/flight-search-results-self-contained.tsx +294 -294
  488. package/src/search-results/features/hotels/hotel-flight-search-results-self-contained.tsx +143 -143
  489. package/src/search-results/features/hotels/hotel-search-results-self-contained.tsx +220 -220
  490. package/src/search-results/features/roundtrips/roundtrip-search-results-self-contained.tsx +65 -65
  491. package/src/search-results/index.tsx +24 -24
  492. package/src/search-results/search-results-configuration-context.ts +6 -6
  493. package/src/search-results/store/search-results-slice.ts +158 -158
  494. package/src/search-results/store/search-results-store.ts +13 -13
  495. package/src/search-results/types.ts +181 -181
  496. package/src/search-results/utils/flight-utils.ts +93 -93
  497. package/src/search-results/utils/search-results-utils.ts +251 -251
  498. package/src/shared/components/flyin/accommodation-flyin.tsx +422 -422
  499. package/src/shared/components/flyin/flights-flyin.tsx +503 -503
  500. package/src/shared/components/flyin/flyin.tsx +82 -82
  501. package/src/shared/components/flyin/group-tour-flyin.tsx +293 -293
  502. package/src/shared/components/icon.tsx +826 -826
  503. package/src/shared/components/loader.tsx +16 -16
  504. package/src/shared/translations/ar-SA.json +381 -381
  505. package/src/shared/translations/da-DK.json +381 -381
  506. package/src/shared/translations/de-DE.json +381 -381
  507. package/src/shared/translations/en-GB.json +385 -385
  508. package/src/shared/translations/es-ES.json +381 -381
  509. package/src/shared/translations/fr-BE.json +385 -385
  510. package/src/shared/translations/fr-FR.json +381 -381
  511. package/src/shared/translations/is-IS.json +381 -381
  512. package/src/shared/translations/it-IT.json +381 -381
  513. package/src/shared/translations/ja-JP.json +381 -381
  514. package/src/shared/translations/nl-BE.json +385 -385
  515. package/src/shared/translations/nl-NL.json +381 -381
  516. package/src/shared/translations/no-NO.json +381 -381
  517. package/src/shared/translations/pl-PL.json +381 -381
  518. package/src/shared/translations/pt-PT.json +381 -381
  519. package/src/shared/translations/sv-SE.json +381 -381
  520. package/src/shared/types.ts +31 -31
  521. package/src/shared/utils/class-util.ts +7 -7
  522. package/src/shared/utils/localization-util.ts +275 -275
  523. package/src/shared/utils/query-string-util.ts +91 -91
  524. package/src/shared/utils/tide-api-utils.ts +34 -34
  525. package/src/shared/utils/use-media-query-util.ts +19 -19
  526. package/styles/abstracts/_mixins.scss +74 -74
  527. package/styles/abstracts/_variables.scss +57 -57
  528. package/styles/base/_fonts.scss +2 -2
  529. package/styles/base/_normalize.scss +227 -227
  530. package/styles/base/_typography.scss +35 -35
  531. package/styles/booking-joker-variables.scss +596 -596
  532. package/styles/booking-product-variables.scss +330 -330
  533. package/styles/booking-product.scss +438 -438
  534. package/styles/booking-qsm-variables.scss +501 -501
  535. package/styles/booking-qsm.scss +52 -52
  536. package/styles/booking-search-results-variables.scss +728 -728
  537. package/styles/booking-search-results.scss +53 -53
  538. package/styles/booking-wizard-variables.scss +603 -603
  539. package/styles/booking-wizard.scss +61 -61
  540. package/styles/components/_accordion.scss +67 -67
  541. package/styles/components/_animations.scss +39 -39
  542. package/styles/components/_base.scss +107 -107
  543. package/styles/components/_booking.scss +872 -872
  544. package/styles/components/_breadcrumb.scss +92 -92
  545. package/styles/components/_button.scss +238 -238
  546. package/styles/components/_checkbox.scss +230 -230
  547. package/styles/components/_contact.scss +239 -239
  548. package/styles/components/_content.scss +336 -336
  549. package/styles/components/_cta.scss +238 -238
  550. package/styles/components/_date-list.scss +41 -41
  551. package/styles/components/_date-range-picker.scss +223 -223
  552. package/styles/components/_decrement-increment.scss +35 -35
  553. package/styles/components/_dropdown.scss +72 -72
  554. package/styles/components/_faq.scss +27 -27
  555. package/styles/components/_flight-option.scss +1419 -1419
  556. package/styles/components/_flyin.scss +727 -727
  557. package/styles/components/_footer.scss +141 -141
  558. package/styles/components/_form.scss +1634 -1634
  559. package/styles/components/_gallery.scss +314 -314
  560. package/styles/components/_header.scss +113 -113
  561. package/styles/components/_image-with-text.scss +206 -206
  562. package/styles/components/_img-slider.scss +175 -175
  563. package/styles/components/_info-message.scss +75 -75
  564. package/styles/components/_input.scss +35 -35
  565. package/styles/components/_list.scss +185 -185
  566. package/styles/components/_loader.scss +70 -70
  567. package/styles/components/_login.scss +140 -140
  568. package/styles/components/_mixins.scss +579 -579
  569. package/styles/components/_navbar.scss +765 -765
  570. package/styles/components/_passenger-picker.scss +306 -306
  571. package/styles/components/_phone-input.scss +8 -8
  572. package/styles/components/_placeholders.scss +165 -165
  573. package/styles/components/_pricing-summary.scss +163 -163
  574. package/styles/components/_qsm.scss +17 -17
  575. package/styles/components/_radiobutton.scss +170 -170
  576. package/styles/components/_search.scss +2009 -2009
  577. package/styles/components/_select-wrapper.scss +76 -76
  578. package/styles/components/_slider.scss +128 -128
  579. package/styles/components/_spinner.scss +29 -29
  580. package/styles/components/_step-indicators.scss +161 -161
  581. package/styles/components/_table.scss +81 -81
  582. package/styles/components/_tree.scss +648 -648
  583. package/styles/components/_typeahead.scss +275 -275
  584. package/styles/components/_variables.scss +89 -89
  585. package/styles/content-blocks-variables.scss +507 -507
  586. package/styles/content-blocks.scss +64 -64
  587. package/styles/font.scss +2 -2
  588. package/styles/qsm/_calendar.scss +274 -274
  589. package/styles/qsm/_qsm.scss +1094 -1094
  590. package/styles/search.scss +1200 -1200
  591. package/tsconfig.json +24 -24
@@ -1,893 +1,893 @@
1
- import React, { useContext, useEffect, useRef, useState } from 'react';
2
- import { useDispatch, useSelector } from 'react-redux';
3
- import { SearchResultsRootState } from '../../store/search-results-store';
4
- import SearchResultsConfigurationContext from '../../search-results-configuration-context';
5
- import {
6
- resetFilters,
7
- setSortType,
8
- setResults,
9
- setIsLoading,
10
- setSelectedSearchResult,
11
- setBookingPackageDetails,
12
- setEntry,
13
- setFlyInIsOpen,
14
- setFilteredResults,
15
- setPackagingAccoResults,
16
- setFilteredPackagingAccoResults,
17
- setPackagingAccoSearchDetails
18
- } from '../../store/search-results-slice';
19
- import { Filter, SortByType } from '../../types';
20
- import useMediaQuery from '../../../shared/utils/use-media-query-util';
21
- import ItemPicker from '../item-picker';
22
- import {
23
- TideClientConfig,
24
- details,
25
- detailsWL,
26
- getEntryLight,
27
- search,
28
- searchPackagingAccommodations,
29
- BookingPackageDestination,
30
- BookingPackageDetailsRequest,
31
- BookingPackagePax,
32
- BookingPackageRequest,
33
- BookingPackageRequestRoom,
34
- BookingPackageSearchRequest,
35
- EntryLight,
36
- EntryRoom,
37
- PackagingAccommodationRequest,
38
- PackagingDestination,
39
- PackagingRoom,
40
- PackagingTraveller,
41
- PortalQsmType
42
- } from '@qite/tide-client';
43
- import { getDateFromParams, getNumberFromParams, getRoomsFromParams, getStringFromParams } from '../../../shared/utils/query-string-util';
44
- import { range } from 'lodash';
45
- import { Room } from '../../../booking-wizard/types';
46
- import Icon from '../icon';
47
- import Itinerary from '../itinerary';
48
- import TabViews from '../tab-views';
49
- import FlyIn from '../../../shared/components/flyin/flyin';
50
- import HotelAccommodationResults from '../hotel/hotel-accommodation-results';
51
- import RoundTripResults from '../round-trip/round-trip-results';
52
- import FlightResults from '../flight/flight-results';
53
- import { findSortByType, getSortingName, getTranslations } from '../../../shared/utils/localization-util';
54
- import { FlightSearchProvider } from '../flight/flight-search-context';
55
- import FlightResultsContainer from './flight-search-results';
56
- import Filters from '../filters/filters';
57
- import GroupTourResults from '../group-tour/group-tour-results';
58
- import {
59
- applyFilters,
60
- applyFiltersToPackageAccoResults,
61
- enrichFiltersWithPackageAccoResults,
62
- enrichFiltersWithResults
63
- } from '../../utils/search-results-utils';
64
-
65
- const SearchResultsContainer: React.FC = () => {
66
- const dispatch = useDispatch();
67
-
68
- const context = useContext(SearchResultsConfigurationContext);
69
- const translations = getTranslations(context?.languageCode ?? 'en-GB');
70
-
71
- const {
72
- results,
73
- filteredResults,
74
- packagingAccoResults,
75
- filteredPackagingAccoResults,
76
- bookingPackageDetails,
77
- entry,
78
- isLoading,
79
- filters,
80
- selectedSortType,
81
- selectedSearchResult,
82
- selectedPackagingAccoResultCode,
83
- flyInIsOpen
84
- } = useSelector((state: SearchResultsRootState) => state.searchResults);
85
-
86
- const isMobile = useMediaQuery('(max-width: 1200px)');
87
-
88
- const [initialFiltersSet, setInitialFiltersSet] = useState(false);
89
- const [initialFilters, setInitialFilters] = useState<Filter[]>([]);
90
- const [filtersOpen, setFiltersOpen] = useState(false);
91
-
92
- const [detailsIsLoading, setDetailsIsLoading] = useState(false);
93
-
94
- const [itineraryOpen, setItineraryOpen] = useState(false);
95
-
96
- const panelRef = useRef<HTMLDivElement | null>(null);
97
-
98
- const sortByTypes: SortByType[] = [
99
- { direction: 'asc', label: 'default' } as SortByType,
100
- { direction: 'asc', label: 'price' } as SortByType,
101
- { direction: 'desc', label: 'price' } as SortByType
102
- ];
103
-
104
- const handleFlyInToggle = (isOpen: boolean) => {
105
- dispatch(setFlyInIsOpen(isOpen));
106
- };
107
-
108
- const handleSortChange = (newSortKey: string, direction?: string) => {
109
- const newSortByType = findSortByType(sortByTypes, newSortKey, direction ?? 'asc');
110
- if (newSortByType) {
111
- dispatch(setSortType(newSortByType));
112
- }
113
- };
114
-
115
- const buildSearchFromEntry = (entry: EntryLight): BookingPackageRequest<BookingPackageSearchRequest> => {
116
- const from = new Date(Math.min(...entry.items.map((i) => i.startDate.getTime()))).toISOString();
117
- const to = new Date(Math.max(...entry.items.map((i) => i.endDate.getTime()))).toISOString();
118
- const rooms = entry.rooms;
119
-
120
- const hotelItem = entry.items.find((i) => i.productType === 3);
121
-
122
- let country = hotelItem ? hotelItem.countryId : null;
123
- let region = hotelItem ? hotelItem.regionId : null;
124
- let oord = hotelItem ? hotelItem.oordId : null;
125
- let city = hotelItem ? hotelItem.locationId : null;
126
- let hotel = hotelItem ? hotelItem.productCode : null;
127
-
128
- if (typeof window !== 'undefined') {
129
- window.scrollTo(0, 0);
130
- }
131
-
132
- let destinationId: number | null = null;
133
- let destinationIsCountry = false;
134
- let destinationIsRegion = false;
135
- let destinationIsOord = false;
136
- let destinationIsLocation = false;
137
-
138
- if (country) {
139
- destinationId = country;
140
- destinationIsCountry = true;
141
- } else if (region) {
142
- destinationId = region;
143
- destinationIsRegion = true;
144
- } else if (oord) {
145
- destinationId = oord;
146
- destinationIsOord = true;
147
- } else if (city) {
148
- destinationId = city;
149
- destinationIsLocation = true;
150
- }
151
-
152
- var searchRequest = {
153
- officeId: 1,
154
- payload: {
155
- catalogueIds: context!.tideConnection.catalogueIds ?? [],
156
- serviceType:
157
- context!.searchConfiguration.qsmType === PortalQsmType.Accommodation || context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight
158
- ? 3
159
- : context!.searchConfiguration.qsmType === PortalQsmType.Flight
160
- ? 7
161
- : context!.searchConfiguration.qsmType === PortalQsmType.RoundTrip
162
- ? 1
163
- : 0,
164
- searchType: 0,
165
- destination: {
166
- id: Number(destinationId),
167
- isCountry: destinationIsCountry,
168
- isRegion: destinationIsRegion,
169
- isOord: destinationIsOord,
170
- isLocation: destinationIsLocation
171
- } as BookingPackageDestination,
172
- rooms: getRequestRoomsFromEntry(rooms),
173
- fromDate: from,
174
- toDate: to,
175
- earliestFromOffset: 0,
176
- latestToOffset: 0,
177
- includeFlights: true,
178
- regimeCodes: entry.items.map((i) => i.regimeCode) || [],
179
- useExactDates: true,
180
- onlyCachedResults: false,
181
- includeAllAllotments: true,
182
- productCodes: hotel ? [hotel] : []
183
- }
184
- };
185
-
186
- return searchRequest;
187
- };
188
-
189
- const buildSearchFromQueryParams = (params: URLSearchParams): BookingPackageRequest<BookingPackageSearchRequest> | null => {
190
- let from = getDateFromParams(params, 'fromDate');
191
- let to = getDateFromParams(params, 'toDate');
192
- const rooms = getRoomsFromParams(params, 'rooms');
193
- let country = getNumberFromParams(params, 'country');
194
- let region = getNumberFromParams(params, 'region');
195
- let oord = getNumberFromParams(params, 'oord');
196
- let city = getNumberFromParams(params, 'location');
197
- let hotel = getNumberFromParams(params, 'hotel');
198
- let tagId = getNumberFromParams(params, 'tagId');
199
-
200
- if (!from || !to) {
201
- console.error('Missing fromDate or toDate in query params, using default values');
202
- return null;
203
- }
204
-
205
- if (typeof window !== 'undefined') {
206
- window.scrollTo(0, 0);
207
- }
208
-
209
- let destinationId: number | null = null;
210
- let destinationIsCountry = false;
211
- let destinationIsRegion = false;
212
- let destinationIsOord = false;
213
- let destinationIsLocation = false;
214
-
215
- if (country) {
216
- destinationId = country;
217
- destinationIsCountry = true;
218
- } else if (region) {
219
- destinationId = region;
220
- destinationIsRegion = true;
221
- } else if (oord) {
222
- destinationId = oord;
223
- destinationIsOord = true;
224
- } else if (city) {
225
- destinationId = city;
226
- destinationIsLocation = true;
227
- }
228
-
229
- var searchRequest = {
230
- officeId: 1,
231
- payload: {
232
- catalogueIds: context!.tideConnection.catalogueIds ?? [],
233
- serviceType:
234
- context!.searchConfiguration.qsmType === PortalQsmType.Accommodation || context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight
235
- ? 3
236
- : context!.searchConfiguration.qsmType === PortalQsmType.Flight
237
- ? 7
238
- : context!.searchConfiguration.qsmType === PortalQsmType.RoundTrip
239
- ? 1
240
- : undefined,
241
- searchType: context!.searchConfiguration.qsmType === PortalQsmType.GroupTour ? 1 : 0,
242
- destination: {
243
- id: Number(destinationId),
244
- isCountry: destinationIsCountry,
245
- isRegion: destinationIsRegion,
246
- isOord: destinationIsOord,
247
- isLocation: destinationIsLocation
248
- } as BookingPackageDestination,
249
- rooms: getRequestRooms(rooms),
250
- fromDate: from,
251
- toDate: to,
252
- earliestFromOffset: 0,
253
- latestToOffset: 0,
254
- includeFlights: context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight ? true : false,
255
- // regimeCodes:
256
- // filters
257
- // .find((f) => f.property === 'regime')
258
- // ?.options?.filter((o) => o.isChecked)
259
- // .flatMap((o) => o.value.toString()) || [],
260
- // minPrice: filters.find((f) => f.property === 'price')?.selectedMin,
261
- // maxPrice: filters.find((f) => f.property === 'price')?.selectedMax,
262
- useExactDates: context?.searchConfiguration.qsmType === PortalQsmType.GroupTour ? false : true,
263
- onlyCachedResults: false,
264
- includeAllAllotments: true,
265
- productIds: hotel ? [hotel] : [],
266
- productTagIds: tagId ? [tagId] : []
267
- }
268
- };
269
-
270
- console.log('Built search request from query params', searchRequest);
271
-
272
- return searchRequest;
273
- };
274
-
275
- const getRequestRoomsFromEntry = (rooms: EntryRoom[] | null) => {
276
- if (!rooms) {
277
- // Fall back to 2 adults
278
- var room = { index: 0, pax: [] } as BookingPackageRequestRoom;
279
- range(0, 2).forEach(() => {
280
- room.pax.push({
281
- age: 30
282
- } as BookingPackagePax);
283
- });
284
- return [room];
285
- }
286
-
287
- const requestRooms = rooms?.map((x, i) => {
288
- var room = { index: i, pax: [] } as BookingPackageRequestRoom;
289
- x.travellers.forEach((p) => {
290
- room.pax.push({
291
- age: p.age,
292
- dateOfBirth: p.dateOfBirth
293
- } as BookingPackagePax);
294
- });
295
-
296
- return room;
297
- });
298
-
299
- return requestRooms;
300
- };
301
-
302
- const getRequestRooms = (rooms: Room[] | null) => {
303
- if (!rooms) {
304
- // Fall back to 2 adults
305
- var room = { index: 0, pax: [] } as BookingPackageRequestRoom;
306
- range(0, 2).forEach(() => {
307
- room.pax.push({
308
- age: 30
309
- } as BookingPackagePax);
310
- });
311
- return [room];
312
- }
313
-
314
- const requestRooms = rooms?.map((x, i) => {
315
- var room = { index: i, pax: [] } as BookingPackageRequestRoom;
316
- range(0, x.adults).forEach(() => {
317
- room.pax.push({
318
- age: 30
319
- } as BookingPackagePax);
320
- });
321
- x.childAges.forEach((x) => {
322
- room.pax.push({
323
- age: x
324
- } as BookingPackagePax);
325
- });
326
- return room;
327
- });
328
-
329
- return requestRooms;
330
- };
331
-
332
- const buildPackagingAccommodationRequestFromQueryParams = (params: URLSearchParams): PackagingAccommodationRequest | null => {
333
- let from = getDateFromParams(params, 'fromDate');
334
- let to = getDateFromParams(params, 'toDate');
335
- const rooms = getRoomsFromParams(params, 'rooms');
336
- let country = getNumberFromParams(params, 'country');
337
- let region = getNumberFromParams(params, 'region');
338
- let oord = getNumberFromParams(params, 'oord');
339
- let city = getNumberFromParams(params, 'location');
340
- let hotel = getNumberFromParams(params, 'hotel');
341
- let tagId = getNumberFromParams(params, 'tagId');
342
- let agentId = getNumberFromParams(params, 'agentId');
343
- let destinationAirport = getStringFromParams(params, 'destinationAirport');
344
-
345
- if (!from || !to) {
346
- console.error('Missing fromDate or toDate in query params, using default values');
347
- return null;
348
- }
349
-
350
- if (typeof window !== 'undefined') {
351
- window.scrollTo(0, 0);
352
- }
353
-
354
- let destinationId: number | null = null;
355
- let destinationIsCountry = false;
356
- let destinationIsRegion = false;
357
- let destinationIsOord = false;
358
- let destinationIsLocation = false;
359
- let destinationCode: string | null = null;
360
- let destinationIsAirport = false;
361
-
362
- if (country) {
363
- destinationId = country;
364
- destinationIsCountry = true;
365
- } else if (region) {
366
- destinationId = region;
367
- destinationIsRegion = true;
368
- } else if (oord) {
369
- destinationId = oord;
370
- destinationIsOord = true;
371
- } else if (city) {
372
- destinationId = city;
373
- destinationIsLocation = true;
374
- } else if (destinationAirport) {
375
- destinationCode = destinationAirport;
376
- destinationIsAirport = true;
377
- }
378
-
379
- var searchRequest = {
380
- officeId: 1,
381
- agentId: agentId ?? null,
382
- catalogueId: context!.searchConfiguration.defaultCatalogueId ?? 0,
383
- searchConfigurationId: context!.searchConfiguration.id,
384
- language: context!.languageCode ?? 'en-GB',
385
- servicesType: 3, // accommodation
386
- fromDate: from,
387
- toDate: to,
388
- destination: {
389
- id: Number(destinationId),
390
- isCountry: destinationIsCountry,
391
- isRegion: destinationIsRegion,
392
- isOord: destinationIsOord,
393
- isLocation: destinationIsLocation,
394
- isAirport: destinationIsAirport,
395
- code: destinationCode
396
- } as PackagingDestination,
397
- productCode: hotel ? hotel.toString() : '',
398
- rooms: getPackagingRequestRooms(rooms),
399
- tagIds: tagId ? [tagId] : []
400
- };
401
-
402
- console.log('Search request for packaging accommodation from query params', searchRequest);
403
-
404
- return searchRequest;
405
- };
406
-
407
- const getPackagingRequestRooms = (rooms: Room[] | null) => {
408
- if (!rooms) {
409
- // Fall back to 2 adults
410
- var room = { index: 0, travellers: [] } as PackagingRoom;
411
- range(0, 2).forEach(() => {
412
- room.travellers.push({
413
- age: 30
414
- } as PackagingTraveller);
415
- });
416
- return [room];
417
- }
418
-
419
- const requestRooms = rooms?.map((x, i) => {
420
- var room = { index: i, travellers: [] } as PackagingRoom;
421
- range(0, x.adults).forEach(() => {
422
- room.travellers.push({
423
- age: 30
424
- } as PackagingTraveller);
425
- });
426
- x.childAges.forEach((x) => {
427
- room.travellers.push({
428
- age: x
429
- } as PackagingTraveller);
430
- });
431
- return room;
432
- });
433
-
434
- return requestRooms;
435
- };
436
-
437
- useEffect(() => {
438
- if (typeof document !== 'undefined') {
439
- document.body.classList.toggle('has-overlay', filtersOpen);
440
- }
441
- }, [filtersOpen]);
442
-
443
- // seperate Search
444
- useEffect(() => {
445
- const runSearch = async () => {
446
- dispatch(setIsLoading(true));
447
- try {
448
- if (!context) {
449
- return;
450
- }
451
-
452
- const config: TideClientConfig = {
453
- host: context.tideConnection.host,
454
- apiKey: context.tideConnection.apiKey
455
- };
456
-
457
- const params = new URLSearchParams(location.search);
458
- let entryId = getStringFromParams(params, 'entryId');
459
- let entryLight: EntryLight | null = null;
460
- // If entryId is present, we want to fetch the details of that entry and use the details to populate the search results, instead of running a search with the other query params
461
-
462
- let searchRequest: BookingPackageRequest<BookingPackageSearchRequest>;
463
-
464
- if (entryId) {
465
- entryLight = await getEntryLight(config, entryId);
466
- // populate itinerary store
467
- dispatch(setEntry({ entry: entryLight }));
468
- searchRequest = buildSearchFromEntry(entryLight);
469
- } else {
470
- const rq = buildSearchFromQueryParams(params);
471
- if (!rq) {
472
- throw new Error('Invalid search parameters');
473
- }
474
-
475
- searchRequest = rq;
476
- }
477
-
478
- searchRequest.agentId = context.agentId;
479
- const packageSearchResults = await search(config, searchRequest);
480
-
481
- console.log('Search results', packageSearchResults);
482
-
483
- const enrichedFilters = enrichFiltersWithResults(packageSearchResults, context.filters, context.tags ?? []);
484
- if (!initialFiltersSet) {
485
- dispatch(resetFilters(enrichedFilters));
486
- setInitialFilters(enrichedFilters);
487
- setInitialFiltersSet(true);
488
- }
489
-
490
- dispatch(setResults(packageSearchResults));
491
- const initialFilteredResults = applyFilters(packageSearchResults, filters, null);
492
- dispatch(setFilteredResults(initialFilteredResults));
493
-
494
- if (packageSearchResults?.length > 0) {
495
- if (entryId) {
496
- const matching = packageSearchResults.find((r) => r.productId === entry?.id);
497
-
498
- if (matching) {
499
- dispatch(setSelectedSearchResult(matching));
500
- }
501
- } else {
502
- if (context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight) {
503
- dispatch(setSelectedSearchResult(packageSearchResults[0]));
504
- }
505
- }
506
- }
507
-
508
- dispatch(setIsLoading(false));
509
- } catch (err) {
510
- console.error('Search failed', err);
511
- dispatch(setIsLoading(false));
512
- }
513
- };
514
-
515
- const runHotelSearch = async () => {
516
- dispatch(setIsLoading(true));
517
- try {
518
- if (!context) {
519
- return;
520
- }
521
-
522
- const config: TideClientConfig = {
523
- host: context.tideConnection.host,
524
- apiKey: context.tideConnection.apiKey
525
- };
526
-
527
- const params = new URLSearchParams(location.search);
528
-
529
- let searchRequest: PackagingAccommodationRequest;
530
-
531
- const rq = buildPackagingAccommodationRequestFromQueryParams(params);
532
- if (!rq) {
533
- throw new Error('Invalid search parameters');
534
- }
535
-
536
- searchRequest = rq;
537
- searchRequest.portalId = context.portalId;
538
- searchRequest.agentId = context.agentId;
539
-
540
- const packageAccoSearchResults = await searchPackagingAccommodations(config, searchRequest);
541
-
542
- console.log('package Acco SearchResults', packageAccoSearchResults);
543
-
544
- const enrichedFilters = enrichFiltersWithPackageAccoResults(packageAccoSearchResults, context.filters, context.tags ?? []);
545
- if (!initialFiltersSet) {
546
- dispatch(resetFilters(enrichedFilters));
547
- setInitialFilters(enrichedFilters);
548
- setInitialFiltersSet(true);
549
- }
550
-
551
- dispatch(setPackagingAccoResults(packageAccoSearchResults));
552
- const initialFilteredResults = applyFiltersToPackageAccoResults(packageAccoSearchResults, filters, null);
553
- dispatch(setFilteredPackagingAccoResults(initialFilteredResults));
554
-
555
- dispatch(setIsLoading(false));
556
- } catch (err) {
557
- console.error('Search failed', err);
558
- dispatch(setIsLoading(false));
559
- }
560
- };
561
-
562
- if (!context?.showMockup) {
563
- if (
564
- context?.searchConfiguration.qsmType === PortalQsmType.GroupTour ||
565
- (context?.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight && !context.searchConfiguration.enableManualPackaging)
566
- ) {
567
- runSearch();
568
- }
569
- if (context?.searchConfiguration.qsmType === PortalQsmType.Accommodation) {
570
- runHotelSearch();
571
- }
572
- if (context?.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight && context.searchConfiguration.enableManualPackaging) {
573
- // Manual packaging flow.
574
- if (context.searchConfiguration.allowAccommodations) {
575
- runHotelSearch();
576
- }
577
- }
578
- }
579
- }, [location.search]);
580
-
581
- // Seperate detailsCall
582
- useEffect(() => {
583
- const fetchDetails = async () => {
584
- setDetailsIsLoading(true);
585
- console.log('Fetching details for selected search result', selectedSearchResult);
586
- if (!selectedSearchResult || !context) return;
587
- if (context?.searchConfiguration.qsmType === PortalQsmType.Accommodation || context?.searchConfiguration.qsmType === PortalQsmType.GroupTour) {
588
- handleFlyInToggle(true);
589
- }
590
-
591
- try {
592
- const config: TideClientConfig = {
593
- host: context.tideConnection.host,
594
- apiKey: context.tideConnection.apiKey
595
- };
596
-
597
- const selectedItem = results.find((r) => r.productId === selectedSearchResult.productId);
598
- if (!selectedItem) {
599
- // TODO: handle this case better, show an error message to the user
600
- return;
601
- }
602
-
603
- const params = new URLSearchParams(location.search);
604
- let entryId = getStringFromParams(params, 'entryId');
605
-
606
- let requestRooms;
607
- if (entry && entryId) {
608
- requestRooms = getRequestRoomsFromEntry(entry.rooms);
609
- } else {
610
- const rooms = getRoomsFromParams(params, 'rooms');
611
- requestRooms = getRequestRooms(rooms);
612
- }
613
-
614
- const detailsRequest: BookingPackageRequest<BookingPackageDetailsRequest> = {
615
- officeId: 1,
616
- payload: {
617
- catalogueId: selectedItem.catalogueId,
618
- rooms: requestRooms,
619
- searchType: 0, // same as search
620
- productCode: selectedItem.code,
621
- fromDate: selectedItem.fromDate,
622
- toDate: selectedItem.toDate,
623
- includeFlights: context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight ? true : false,
624
- includeHotels: true,
625
- includePaxTypes: true,
626
- checkExternalAvailability: true,
627
- expectedPrice: selectedItem.price,
628
- duration: null,
629
- preNights: null,
630
- postNights: null
631
- },
632
- agentId: context.agentId
633
- };
634
-
635
- if (entry && entryId) {
636
- requestRooms = getRequestRoomsFromEntry(entry.rooms);
637
- const detailsResponse = await details(config, detailsRequest);
638
- console.log('Details:', detailsResponse);
639
- dispatch(setBookingPackageDetails({ details: detailsResponse?.payload }));
640
- } else {
641
- // const detailsWLResponse = await detailsWL(config, detailsRequest);
642
- // console.log('Details with entryLight:', detailsWLResponse);
643
- // dispatch(setBookingPackageDetails({ details: detailsWLResponse?.payload?.bookingPackage }));
644
- // dispatch(setEntry({ entry: detailsWLResponse?.payload?.entry }));
645
-
646
- const detailsResponse = await details(config, detailsRequest);
647
- dispatch(setBookingPackageDetails({ details: detailsResponse?.payload }));
648
- setDetailsIsLoading(false);
649
- }
650
- } catch (err) {
651
- console.error('Failed to fetch package details', err);
652
- setDetailsIsLoading(false);
653
- }
654
- };
655
-
656
- const fetchPackagingAccoSearchDetails = async () => {
657
- if (!selectedPackagingAccoResultCode || !context) return;
658
-
659
- if (context?.searchConfiguration.qsmType === PortalQsmType.Accommodation || context?.searchConfiguration.qsmType === PortalQsmType.GroupTour) {
660
- handleFlyInToggle(true);
661
- }
662
-
663
- try {
664
- const config: TideClientConfig = {
665
- host: context.tideConnection.host,
666
- apiKey: context.tideConnection.apiKey
667
- };
668
-
669
- console.log('selectedPackagingAccoResultCode', selectedPackagingAccoResultCode);
670
- const selectedItem = packagingAccoResults.find((r) => r.code === selectedPackagingAccoResultCode);
671
- console.log('Selected packaging acco item', selectedItem);
672
- if (!selectedItem) {
673
- // TODO: handle this case better, show an error message to the user
674
- return;
675
- }
676
-
677
- const params = new URLSearchParams(location.search);
678
- const rooms = getRoomsFromParams(params, 'rooms');
679
- let tagId = getNumberFromParams(params, 'tagId');
680
-
681
- let destinationAirport = getStringFromParams(params, 'destinationAirport');
682
-
683
- let destinationId: number | null = null;
684
- let destinationIsCountry = false;
685
- let destinationIsRegion = false;
686
- let destinationIsOord = false;
687
- let destinationIsLocation = false;
688
- let destinationCode: string | null = null;
689
- let destinationIsAirport = false;
690
-
691
- if (selectedItem.countryId) {
692
- destinationId = selectedItem.countryId;
693
- destinationIsCountry = true;
694
- } else if (selectedItem.regionId) {
695
- destinationId = selectedItem.regionId;
696
- destinationIsRegion = true;
697
- } else if (selectedItem.oordId) {
698
- destinationId = selectedItem.oordId;
699
- destinationIsOord = true;
700
- } else if (selectedItem.locationId) {
701
- destinationId = selectedItem.locationId;
702
- destinationIsLocation = true;
703
- } else if (destinationAirport) {
704
- destinationCode = destinationAirport;
705
- destinationIsAirport = true;
706
- }
707
-
708
- const detailSearchRequest: PackagingAccommodationRequest = {
709
- officeId: 1,
710
- portalId: context.portalId,
711
- agentId: context.agentId,
712
- catalogueId: context!.searchConfiguration.defaultCatalogueId ?? 0,
713
- searchConfigurationId: context!.searchConfiguration.id,
714
- vendorConfigurationId: selectedItem.vendorId,
715
- language: context!.languageCode ?? 'en-GB',
716
- serviceType: 3,
717
- fromDate: selectedItem.fromDate,
718
- toDate: selectedItem.toDate,
719
- destination: {
720
- id: Number(destinationId),
721
- isCountry: destinationIsCountry,
722
- isRegion: destinationIsRegion,
723
- isOord: destinationIsOord,
724
- isLocation: destinationIsLocation,
725
- isAirport: destinationIsAirport,
726
- code: destinationCode
727
- } as PackagingDestination,
728
- productCode: selectedItem.code ? selectedItem.code : '',
729
- rooms: getPackagingRequestRooms(rooms),
730
- tagIds: tagId ? [tagId] : []
731
- };
732
-
733
- const packageAccoSearchDetails = await searchPackagingAccommodations(config, detailSearchRequest);
734
- console.log('Packaging Acco Search details', packageAccoSearchDetails);
735
- dispatch(setPackagingAccoSearchDetails(packageAccoSearchDetails));
736
- } catch (err) {
737
- console.error('Failed to fetch package details', err);
738
- }
739
- };
740
-
741
- if (selectedSearchResult) {
742
- fetchDetails();
743
- }
744
- if (selectedPackagingAccoResultCode) {
745
- fetchPackagingAccoSearchDetails();
746
- }
747
- }, [selectedSearchResult, selectedPackagingAccoResultCode]);
748
-
749
- useEffect(() => {
750
- if (context?.searchConfiguration.qsmType === PortalQsmType.Accommodation) {
751
- const filteredPackageAccoResults = applyFiltersToPackageAccoResults(packagingAccoResults, filters, selectedSortType);
752
- dispatch(setFilteredPackagingAccoResults(filteredPackageAccoResults));
753
- } else {
754
- const filteredResults = applyFilters(results, filters, selectedSortType);
755
- dispatch(setFilteredResults(filteredResults));
756
- }
757
- }, [filters, results, packagingAccoResults, selectedSortType]);
758
-
759
- return (
760
- <div id="tide-booking" className="search__bg">
761
- {context && (
762
- <div className="search">
763
- <div className="search__container">
764
- {context.searchConfiguration.qsmType === PortalQsmType.Flight && (
765
- <FlightSearchProvider tideConnection={context.tideConnection}>
766
- <FlightResultsContainer isMobile={isMobile} />
767
- <FlyIn
768
- title="Select your fare"
769
- srpType={context.searchConfiguration.qsmType}
770
- isOpen={flyInIsOpen}
771
- setIsOpen={handleFlyInToggle}
772
- onPanelRef={(el) => (panelRef.current = el)}
773
- detailsLoading={detailsIsLoading}
774
- />
775
- </FlightSearchProvider>
776
- )}
777
- {(context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight ||
778
- context.searchConfiguration.qsmType === PortalQsmType.Accommodation ||
779
- context.searchConfiguration.qsmType === PortalQsmType.GroupTour ||
780
- context.searchConfiguration.qsmType === PortalQsmType.RoundTrip) && (
781
- <>
782
- {context.searchConfiguration.qsmType != PortalQsmType.AccommodationAndFlight && context.showFilters && (
783
- <Filters
784
- initialFilters={initialFilters}
785
- filters={filters}
786
- isOpen={filtersOpen}
787
- handleSetIsOpen={() => setFiltersOpen(!filtersOpen)}
788
- // handleApplyFilters={() => setSearchTrigger((prev) => prev + 1)}
789
- isLoading={isLoading}
790
- />
791
- )}
792
- {context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight && (
793
- <Itinerary isOpen={itineraryOpen} handleSetIsOpen={() => setItineraryOpen(!itineraryOpen)} isLoading={isLoading} />
794
- )}
795
- {/* ---------------- Results ---------------- */}
796
- <div className="search__results">
797
- {isMobile && (
798
- <div className="search__result-row">
799
- <div className="search__results__actions">
800
- {context.searchConfiguration.qsmType != PortalQsmType.AccommodationAndFlight && context.showFilters && (
801
- <div className="cta cta--filter" onClick={() => setFiltersOpen(true)}>
802
- <Icon name="ui-filter" className="mobile-filters-button__icon" height={16} />
803
- {translations.SRP.FILTERS}
804
- </div>
805
- )}
806
- {context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight && (
807
- <div className="cta cta--filter" onClick={() => setItineraryOpen(true)}>
808
- <Icon name="ui-calendar" className="mobile-filters-button__icon" height={16} />
809
- {translations.SRP.SHOW_ITINERARY}
810
- </div>
811
- )}
812
- </div>
813
- {sortByTypes && sortByTypes.length > 0 && (
814
- <ItemPicker
815
- items={sortByTypes}
816
- selection={selectedSortType?.label || undefined}
817
- selectedSortByType={selectedSortType}
818
- label={translations.SRP.SORTBY}
819
- placeholder={translations.SRP.SORTBY}
820
- classModifier="travel-class-picker__items"
821
- valueFormatter={(value, direction) => getSortingName(translations, findSortByType(sortByTypes, value, direction ?? 'asc'))}
822
- onPick={(newSortKey, direction) => handleSortChange(newSortKey, direction)}
823
- />
824
- )}
825
- </div>
826
- )}
827
- <div className="search__result-row">
828
- <span className="search__result-row-text">
829
- {!isLoading && (
830
- <>
831
- {((context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight &&
832
- context.searchConfiguration.enableManualPackaging) ||
833
- context.searchConfiguration.qsmType === PortalQsmType.Accommodation) &&
834
- filteredPackagingAccoResults?.length &&
835
- filteredPackagingAccoResults?.length}
836
- {context.searchConfiguration.qsmType !== PortalQsmType.Accommodation && filteredResults?.length && filteredResults.length}
837
- &nbsp;{translations.SRP.TOTAL_RESULTS_LABEL}
838
- </>
839
- )}
840
- </span>
841
- {!isMobile && sortByTypes && sortByTypes.length > 0 && (
842
- <div className="search__result-row-filter">
843
- <ItemPicker
844
- items={sortByTypes}
845
- selection={selectedSortType?.label || undefined}
846
- selectedSortByType={selectedSortType}
847
- label={translations.SRP.SORTBY}
848
- placeholder={translations.SRP.SORTBY}
849
- classModifier="travel-class-picker__items"
850
- valueFormatter={(value, direction) => getSortingName(translations, findSortByType(sortByTypes, value, direction ?? 'asc'))}
851
- onPick={(newSortKey, direction) => handleSortChange(newSortKey, direction)}
852
- />
853
- </div>
854
- )}
855
- </div>
856
-
857
- <div className="search__results__wrapper">
858
- {context.showTabViews && <TabViews />}
859
-
860
- {context.showRoundTripResults && context.showMockup && <RoundTripResults />}
861
-
862
- {context.searchConfiguration.qsmType === PortalQsmType.GroupTour && <GroupTourResults isLoading={isLoading} />}
863
-
864
- {context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight &&
865
- context.showFlightResults &&
866
- bookingPackageDetails?.outwardFlights && <FlightResults flights={bookingPackageDetails?.outwardFlights} isDeparture={true} />}
867
-
868
- {context.showHotelAccommodationResults && <HotelAccommodationResults isLoading={isLoading} />}
869
-
870
- {context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight &&
871
- context.showFlightResults &&
872
- bookingPackageDetails?.returnFlights && <FlightResults flights={bookingPackageDetails?.returnFlights} isDeparture={false} />}
873
- </div>
874
- </div>
875
- {/* <button onClick={() => handleFlyInToggle(!flyInIsOpen)}>Toggle FlyIn</button> */}
876
- <FlyIn
877
- title={`${translations.SRP.SELECT} ${translations.SRP.ACCOMMODATION}`}
878
- srpType={context.searchConfiguration.qsmType}
879
- isOpen={flyInIsOpen}
880
- setIsOpen={handleFlyInToggle}
881
- onPanelRef={(el) => (panelRef.current = el)}
882
- detailsLoading={detailsIsLoading}
883
- />
884
- </>
885
- )}
886
- </div>
887
- </div>
888
- )}
889
- </div>
890
- );
891
- };
892
-
893
- export default SearchResultsContainer;
1
+ import React, { useContext, useEffect, useRef, useState } from 'react';
2
+ import { useDispatch, useSelector } from 'react-redux';
3
+ import { SearchResultsRootState } from '../../store/search-results-store';
4
+ import SearchResultsConfigurationContext from '../../search-results-configuration-context';
5
+ import {
6
+ resetFilters,
7
+ setSortType,
8
+ setResults,
9
+ setIsLoading,
10
+ setSelectedSearchResult,
11
+ setBookingPackageDetails,
12
+ setEntry,
13
+ setFlyInIsOpen,
14
+ setFilteredResults,
15
+ setPackagingAccoResults,
16
+ setFilteredPackagingAccoResults,
17
+ setPackagingAccoSearchDetails
18
+ } from '../../store/search-results-slice';
19
+ import { Filter, SortByType } from '../../types';
20
+ import useMediaQuery from '../../../shared/utils/use-media-query-util';
21
+ import ItemPicker from '../item-picker';
22
+ import {
23
+ TideClientConfig,
24
+ details,
25
+ detailsWL,
26
+ getEntryLight,
27
+ search,
28
+ searchPackagingAccommodations,
29
+ BookingPackageDestination,
30
+ BookingPackageDetailsRequest,
31
+ BookingPackagePax,
32
+ BookingPackageRequest,
33
+ BookingPackageRequestRoom,
34
+ BookingPackageSearchRequest,
35
+ EntryLight,
36
+ EntryRoom,
37
+ PackagingAccommodationRequest,
38
+ PackagingDestination,
39
+ PackagingRoom,
40
+ PackagingTraveller,
41
+ PortalQsmType
42
+ } from '@qite/tide-client';
43
+ import { getDateFromParams, getNumberFromParams, getRoomsFromParams, getStringFromParams } from '../../../shared/utils/query-string-util';
44
+ import { range } from 'lodash';
45
+ import { Room } from '../../../booking-wizard/types';
46
+ import Icon from '../icon';
47
+ import Itinerary from '../itinerary';
48
+ import TabViews from '../tab-views';
49
+ import FlyIn from '../../../shared/components/flyin/flyin';
50
+ import HotelAccommodationResults from '../hotel/hotel-accommodation-results';
51
+ import RoundTripResults from '../round-trip/round-trip-results';
52
+ import FlightResults from '../flight/flight-results';
53
+ import { findSortByType, getSortingName, getTranslations } from '../../../shared/utils/localization-util';
54
+ import { FlightSearchProvider } from '../flight/flight-search-context';
55
+ import FlightResultsContainer from './flight-search-results';
56
+ import Filters from '../filters/filters';
57
+ import GroupTourResults from '../group-tour/group-tour-results';
58
+ import {
59
+ applyFilters,
60
+ applyFiltersToPackageAccoResults,
61
+ enrichFiltersWithPackageAccoResults,
62
+ enrichFiltersWithResults
63
+ } from '../../utils/search-results-utils';
64
+
65
+ const SearchResultsContainer: React.FC = () => {
66
+ const dispatch = useDispatch();
67
+
68
+ const context = useContext(SearchResultsConfigurationContext);
69
+ const translations = getTranslations(context?.languageCode ?? 'en-GB');
70
+
71
+ const {
72
+ results,
73
+ filteredResults,
74
+ packagingAccoResults,
75
+ filteredPackagingAccoResults,
76
+ bookingPackageDetails,
77
+ entry,
78
+ isLoading,
79
+ filters,
80
+ selectedSortType,
81
+ selectedSearchResult,
82
+ selectedPackagingAccoResultCode,
83
+ flyInIsOpen
84
+ } = useSelector((state: SearchResultsRootState) => state.searchResults);
85
+
86
+ const isMobile = useMediaQuery('(max-width: 1200px)');
87
+
88
+ const [initialFiltersSet, setInitialFiltersSet] = useState(false);
89
+ const [initialFilters, setInitialFilters] = useState<Filter[]>([]);
90
+ const [filtersOpen, setFiltersOpen] = useState(false);
91
+
92
+ const [detailsIsLoading, setDetailsIsLoading] = useState(false);
93
+
94
+ const [itineraryOpen, setItineraryOpen] = useState(false);
95
+
96
+ const panelRef = useRef<HTMLDivElement | null>(null);
97
+
98
+ const sortByTypes: SortByType[] = [
99
+ { direction: 'asc', label: 'default' } as SortByType,
100
+ { direction: 'asc', label: 'price' } as SortByType,
101
+ { direction: 'desc', label: 'price' } as SortByType
102
+ ];
103
+
104
+ const handleFlyInToggle = (isOpen: boolean) => {
105
+ dispatch(setFlyInIsOpen(isOpen));
106
+ };
107
+
108
+ const handleSortChange = (newSortKey: string, direction?: string) => {
109
+ const newSortByType = findSortByType(sortByTypes, newSortKey, direction ?? 'asc');
110
+ if (newSortByType) {
111
+ dispatch(setSortType(newSortByType));
112
+ }
113
+ };
114
+
115
+ const buildSearchFromEntry = (entry: EntryLight): BookingPackageRequest<BookingPackageSearchRequest> => {
116
+ const from = new Date(Math.min(...entry.items.map((i) => i.startDate.getTime()))).toISOString();
117
+ const to = new Date(Math.max(...entry.items.map((i) => i.endDate.getTime()))).toISOString();
118
+ const rooms = entry.rooms;
119
+
120
+ const hotelItem = entry.items.find((i) => i.productType === 3);
121
+
122
+ let country = hotelItem ? hotelItem.countryId : null;
123
+ let region = hotelItem ? hotelItem.regionId : null;
124
+ let oord = hotelItem ? hotelItem.oordId : null;
125
+ let city = hotelItem ? hotelItem.locationId : null;
126
+ let hotel = hotelItem ? hotelItem.productCode : null;
127
+
128
+ if (typeof window !== 'undefined') {
129
+ window.scrollTo(0, 0);
130
+ }
131
+
132
+ let destinationId: number | null = null;
133
+ let destinationIsCountry = false;
134
+ let destinationIsRegion = false;
135
+ let destinationIsOord = false;
136
+ let destinationIsLocation = false;
137
+
138
+ if (country) {
139
+ destinationId = country;
140
+ destinationIsCountry = true;
141
+ } else if (region) {
142
+ destinationId = region;
143
+ destinationIsRegion = true;
144
+ } else if (oord) {
145
+ destinationId = oord;
146
+ destinationIsOord = true;
147
+ } else if (city) {
148
+ destinationId = city;
149
+ destinationIsLocation = true;
150
+ }
151
+
152
+ var searchRequest = {
153
+ officeId: 1,
154
+ payload: {
155
+ catalogueIds: context!.tideConnection.catalogueIds ?? [],
156
+ serviceType:
157
+ context!.searchConfiguration.qsmType === PortalQsmType.Accommodation || context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight
158
+ ? 3
159
+ : context!.searchConfiguration.qsmType === PortalQsmType.Flight
160
+ ? 7
161
+ : context!.searchConfiguration.qsmType === PortalQsmType.RoundTrip
162
+ ? 1
163
+ : 0,
164
+ searchType: 0,
165
+ destination: {
166
+ id: Number(destinationId),
167
+ isCountry: destinationIsCountry,
168
+ isRegion: destinationIsRegion,
169
+ isOord: destinationIsOord,
170
+ isLocation: destinationIsLocation
171
+ } as BookingPackageDestination,
172
+ rooms: getRequestRoomsFromEntry(rooms),
173
+ fromDate: from,
174
+ toDate: to,
175
+ earliestFromOffset: 0,
176
+ latestToOffset: 0,
177
+ includeFlights: true,
178
+ regimeCodes: entry.items.map((i) => i.regimeCode) || [],
179
+ useExactDates: true,
180
+ onlyCachedResults: false,
181
+ includeAllAllotments: true,
182
+ productCodes: hotel ? [hotel] : []
183
+ }
184
+ };
185
+
186
+ return searchRequest;
187
+ };
188
+
189
+ const buildSearchFromQueryParams = (params: URLSearchParams): BookingPackageRequest<BookingPackageSearchRequest> | null => {
190
+ let from = getDateFromParams(params, 'fromDate');
191
+ let to = getDateFromParams(params, 'toDate');
192
+ const rooms = getRoomsFromParams(params, 'rooms');
193
+ let country = getNumberFromParams(params, 'country');
194
+ let region = getNumberFromParams(params, 'region');
195
+ let oord = getNumberFromParams(params, 'oord');
196
+ let city = getNumberFromParams(params, 'location');
197
+ let hotel = getNumberFromParams(params, 'hotel');
198
+ let tagId = getNumberFromParams(params, 'tagId');
199
+
200
+ if (!from || !to) {
201
+ console.error('Missing fromDate or toDate in query params, using default values');
202
+ return null;
203
+ }
204
+
205
+ if (typeof window !== 'undefined') {
206
+ window.scrollTo(0, 0);
207
+ }
208
+
209
+ let destinationId: number | null = null;
210
+ let destinationIsCountry = false;
211
+ let destinationIsRegion = false;
212
+ let destinationIsOord = false;
213
+ let destinationIsLocation = false;
214
+
215
+ if (country) {
216
+ destinationId = country;
217
+ destinationIsCountry = true;
218
+ } else if (region) {
219
+ destinationId = region;
220
+ destinationIsRegion = true;
221
+ } else if (oord) {
222
+ destinationId = oord;
223
+ destinationIsOord = true;
224
+ } else if (city) {
225
+ destinationId = city;
226
+ destinationIsLocation = true;
227
+ }
228
+
229
+ var searchRequest = {
230
+ officeId: 1,
231
+ payload: {
232
+ catalogueIds: context!.tideConnection.catalogueIds ?? [],
233
+ serviceType:
234
+ context!.searchConfiguration.qsmType === PortalQsmType.Accommodation || context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight
235
+ ? 3
236
+ : context!.searchConfiguration.qsmType === PortalQsmType.Flight
237
+ ? 7
238
+ : context!.searchConfiguration.qsmType === PortalQsmType.RoundTrip
239
+ ? 1
240
+ : undefined,
241
+ searchType: context!.searchConfiguration.qsmType === PortalQsmType.GroupTour ? 1 : 0,
242
+ destination: {
243
+ id: Number(destinationId),
244
+ isCountry: destinationIsCountry,
245
+ isRegion: destinationIsRegion,
246
+ isOord: destinationIsOord,
247
+ isLocation: destinationIsLocation
248
+ } as BookingPackageDestination,
249
+ rooms: getRequestRooms(rooms),
250
+ fromDate: from,
251
+ toDate: to,
252
+ earliestFromOffset: 0,
253
+ latestToOffset: 0,
254
+ includeFlights: context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight ? true : false,
255
+ // regimeCodes:
256
+ // filters
257
+ // .find((f) => f.property === 'regime')
258
+ // ?.options?.filter((o) => o.isChecked)
259
+ // .flatMap((o) => o.value.toString()) || [],
260
+ // minPrice: filters.find((f) => f.property === 'price')?.selectedMin,
261
+ // maxPrice: filters.find((f) => f.property === 'price')?.selectedMax,
262
+ useExactDates: context?.searchConfiguration.qsmType === PortalQsmType.GroupTour ? false : true,
263
+ onlyCachedResults: false,
264
+ includeAllAllotments: true,
265
+ productIds: hotel ? [hotel] : [],
266
+ productTagIds: tagId ? [tagId] : []
267
+ }
268
+ };
269
+
270
+ console.log('Built search request from query params', searchRequest);
271
+
272
+ return searchRequest;
273
+ };
274
+
275
+ const getRequestRoomsFromEntry = (rooms: EntryRoom[] | null) => {
276
+ if (!rooms) {
277
+ // Fall back to 2 adults
278
+ var room = { index: 0, pax: [] } as BookingPackageRequestRoom;
279
+ range(0, 2).forEach(() => {
280
+ room.pax.push({
281
+ age: 30
282
+ } as BookingPackagePax);
283
+ });
284
+ return [room];
285
+ }
286
+
287
+ const requestRooms = rooms?.map((x, i) => {
288
+ var room = { index: i, pax: [] } as BookingPackageRequestRoom;
289
+ x.travellers.forEach((p) => {
290
+ room.pax.push({
291
+ age: p.age,
292
+ dateOfBirth: p.dateOfBirth
293
+ } as BookingPackagePax);
294
+ });
295
+
296
+ return room;
297
+ });
298
+
299
+ return requestRooms;
300
+ };
301
+
302
+ const getRequestRooms = (rooms: Room[] | null) => {
303
+ if (!rooms) {
304
+ // Fall back to 2 adults
305
+ var room = { index: 0, pax: [] } as BookingPackageRequestRoom;
306
+ range(0, 2).forEach(() => {
307
+ room.pax.push({
308
+ age: 30
309
+ } as BookingPackagePax);
310
+ });
311
+ return [room];
312
+ }
313
+
314
+ const requestRooms = rooms?.map((x, i) => {
315
+ var room = { index: i, pax: [] } as BookingPackageRequestRoom;
316
+ range(0, x.adults).forEach(() => {
317
+ room.pax.push({
318
+ age: 30
319
+ } as BookingPackagePax);
320
+ });
321
+ x.childAges.forEach((x) => {
322
+ room.pax.push({
323
+ age: x
324
+ } as BookingPackagePax);
325
+ });
326
+ return room;
327
+ });
328
+
329
+ return requestRooms;
330
+ };
331
+
332
+ const buildPackagingAccommodationRequestFromQueryParams = (params: URLSearchParams): PackagingAccommodationRequest | null => {
333
+ let from = getDateFromParams(params, 'fromDate');
334
+ let to = getDateFromParams(params, 'toDate');
335
+ const rooms = getRoomsFromParams(params, 'rooms');
336
+ let country = getNumberFromParams(params, 'country');
337
+ let region = getNumberFromParams(params, 'region');
338
+ let oord = getNumberFromParams(params, 'oord');
339
+ let city = getNumberFromParams(params, 'location');
340
+ let hotel = getNumberFromParams(params, 'hotel');
341
+ let tagId = getNumberFromParams(params, 'tagId');
342
+ let agentId = getNumberFromParams(params, 'agentId');
343
+ let destinationAirport = getStringFromParams(params, 'destinationAirport');
344
+
345
+ if (!from || !to) {
346
+ console.error('Missing fromDate or toDate in query params, using default values');
347
+ return null;
348
+ }
349
+
350
+ if (typeof window !== 'undefined') {
351
+ window.scrollTo(0, 0);
352
+ }
353
+
354
+ let destinationId: number | null = null;
355
+ let destinationIsCountry = false;
356
+ let destinationIsRegion = false;
357
+ let destinationIsOord = false;
358
+ let destinationIsLocation = false;
359
+ let destinationCode: string | null = null;
360
+ let destinationIsAirport = false;
361
+
362
+ if (country) {
363
+ destinationId = country;
364
+ destinationIsCountry = true;
365
+ } else if (region) {
366
+ destinationId = region;
367
+ destinationIsRegion = true;
368
+ } else if (oord) {
369
+ destinationId = oord;
370
+ destinationIsOord = true;
371
+ } else if (city) {
372
+ destinationId = city;
373
+ destinationIsLocation = true;
374
+ } else if (destinationAirport) {
375
+ destinationCode = destinationAirport;
376
+ destinationIsAirport = true;
377
+ }
378
+
379
+ var searchRequest = {
380
+ officeId: 1,
381
+ agentId: agentId ?? null,
382
+ catalogueId: context!.searchConfiguration.defaultCatalogueId ?? 0,
383
+ searchConfigurationId: context!.searchConfiguration.id,
384
+ language: context!.languageCode ?? 'en-GB',
385
+ servicesType: 3, // accommodation
386
+ fromDate: from,
387
+ toDate: to,
388
+ destination: {
389
+ id: Number(destinationId),
390
+ isCountry: destinationIsCountry,
391
+ isRegion: destinationIsRegion,
392
+ isOord: destinationIsOord,
393
+ isLocation: destinationIsLocation,
394
+ isAirport: destinationIsAirport,
395
+ code: destinationCode
396
+ } as PackagingDestination,
397
+ productCode: hotel ? hotel.toString() : '',
398
+ rooms: getPackagingRequestRooms(rooms),
399
+ tagIds: tagId ? [tagId] : []
400
+ };
401
+
402
+ console.log('Search request for packaging accommodation from query params', searchRequest);
403
+
404
+ return searchRequest;
405
+ };
406
+
407
+ const getPackagingRequestRooms = (rooms: Room[] | null) => {
408
+ if (!rooms) {
409
+ // Fall back to 2 adults
410
+ var room = { index: 0, travellers: [] } as PackagingRoom;
411
+ range(0, 2).forEach(() => {
412
+ room.travellers.push({
413
+ age: 30
414
+ } as PackagingTraveller);
415
+ });
416
+ return [room];
417
+ }
418
+
419
+ const requestRooms = rooms?.map((x, i) => {
420
+ var room = { index: i, travellers: [] } as PackagingRoom;
421
+ range(0, x.adults).forEach(() => {
422
+ room.travellers.push({
423
+ age: 30
424
+ } as PackagingTraveller);
425
+ });
426
+ x.childAges.forEach((x) => {
427
+ room.travellers.push({
428
+ age: x
429
+ } as PackagingTraveller);
430
+ });
431
+ return room;
432
+ });
433
+
434
+ return requestRooms;
435
+ };
436
+
437
+ useEffect(() => {
438
+ if (typeof document !== 'undefined') {
439
+ document.body.classList.toggle('has-overlay', filtersOpen);
440
+ }
441
+ }, [filtersOpen]);
442
+
443
+ // seperate Search
444
+ useEffect(() => {
445
+ const runSearch = async () => {
446
+ dispatch(setIsLoading(true));
447
+ try {
448
+ if (!context) {
449
+ return;
450
+ }
451
+
452
+ const config: TideClientConfig = {
453
+ host: context.tideConnection.host,
454
+ apiKey: context.tideConnection.apiKey
455
+ };
456
+
457
+ const params = new URLSearchParams(location.search);
458
+ let entryId = getStringFromParams(params, 'entryId');
459
+ let entryLight: EntryLight | null = null;
460
+ // If entryId is present, we want to fetch the details of that entry and use the details to populate the search results, instead of running a search with the other query params
461
+
462
+ let searchRequest: BookingPackageRequest<BookingPackageSearchRequest>;
463
+
464
+ if (entryId) {
465
+ entryLight = await getEntryLight(config, entryId);
466
+ // populate itinerary store
467
+ dispatch(setEntry({ entry: entryLight }));
468
+ searchRequest = buildSearchFromEntry(entryLight);
469
+ } else {
470
+ const rq = buildSearchFromQueryParams(params);
471
+ if (!rq) {
472
+ throw new Error('Invalid search parameters');
473
+ }
474
+
475
+ searchRequest = rq;
476
+ }
477
+
478
+ searchRequest.agentId = context.agentId;
479
+ const packageSearchResults = await search(config, searchRequest);
480
+
481
+ console.log('Search results', packageSearchResults);
482
+
483
+ const enrichedFilters = enrichFiltersWithResults(packageSearchResults, context.filters, context.tags ?? []);
484
+ if (!initialFiltersSet) {
485
+ dispatch(resetFilters(enrichedFilters));
486
+ setInitialFilters(enrichedFilters);
487
+ setInitialFiltersSet(true);
488
+ }
489
+
490
+ dispatch(setResults(packageSearchResults));
491
+ const initialFilteredResults = applyFilters(packageSearchResults, filters, null);
492
+ dispatch(setFilteredResults(initialFilteredResults));
493
+
494
+ if (packageSearchResults?.length > 0) {
495
+ if (entryId) {
496
+ const matching = packageSearchResults.find((r) => r.productId === entry?.id);
497
+
498
+ if (matching) {
499
+ dispatch(setSelectedSearchResult(matching));
500
+ }
501
+ } else {
502
+ if (context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight) {
503
+ dispatch(setSelectedSearchResult(packageSearchResults[0]));
504
+ }
505
+ }
506
+ }
507
+
508
+ dispatch(setIsLoading(false));
509
+ } catch (err) {
510
+ console.error('Search failed', err);
511
+ dispatch(setIsLoading(false));
512
+ }
513
+ };
514
+
515
+ const runHotelSearch = async () => {
516
+ dispatch(setIsLoading(true));
517
+ try {
518
+ if (!context) {
519
+ return;
520
+ }
521
+
522
+ const config: TideClientConfig = {
523
+ host: context.tideConnection.host,
524
+ apiKey: context.tideConnection.apiKey
525
+ };
526
+
527
+ const params = new URLSearchParams(location.search);
528
+
529
+ let searchRequest: PackagingAccommodationRequest;
530
+
531
+ const rq = buildPackagingAccommodationRequestFromQueryParams(params);
532
+ if (!rq) {
533
+ throw new Error('Invalid search parameters');
534
+ }
535
+
536
+ searchRequest = rq;
537
+ searchRequest.portalId = context.portalId;
538
+ searchRequest.agentId = context.agentId;
539
+
540
+ const packageAccoSearchResults = await searchPackagingAccommodations(config, searchRequest);
541
+
542
+ console.log('package Acco SearchResults', packageAccoSearchResults);
543
+
544
+ const enrichedFilters = enrichFiltersWithPackageAccoResults(packageAccoSearchResults, context.filters, context.tags ?? []);
545
+ if (!initialFiltersSet) {
546
+ dispatch(resetFilters(enrichedFilters));
547
+ setInitialFilters(enrichedFilters);
548
+ setInitialFiltersSet(true);
549
+ }
550
+
551
+ dispatch(setPackagingAccoResults(packageAccoSearchResults));
552
+ const initialFilteredResults = applyFiltersToPackageAccoResults(packageAccoSearchResults, filters, null);
553
+ dispatch(setFilteredPackagingAccoResults(initialFilteredResults));
554
+
555
+ dispatch(setIsLoading(false));
556
+ } catch (err) {
557
+ console.error('Search failed', err);
558
+ dispatch(setIsLoading(false));
559
+ }
560
+ };
561
+
562
+ if (!context?.showMockup) {
563
+ if (
564
+ context?.searchConfiguration.qsmType === PortalQsmType.GroupTour ||
565
+ (context?.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight && !context.searchConfiguration.enableManualPackaging)
566
+ ) {
567
+ runSearch();
568
+ }
569
+ if (context?.searchConfiguration.qsmType === PortalQsmType.Accommodation) {
570
+ runHotelSearch();
571
+ }
572
+ if (context?.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight && context.searchConfiguration.enableManualPackaging) {
573
+ // Manual packaging flow.
574
+ if (context.searchConfiguration.allowAccommodations) {
575
+ runHotelSearch();
576
+ }
577
+ }
578
+ }
579
+ }, [location.search]);
580
+
581
+ // Seperate detailsCall
582
+ useEffect(() => {
583
+ const fetchDetails = async () => {
584
+ setDetailsIsLoading(true);
585
+ console.log('Fetching details for selected search result', selectedSearchResult);
586
+ if (!selectedSearchResult || !context) return;
587
+ if (context?.searchConfiguration.qsmType === PortalQsmType.Accommodation || context?.searchConfiguration.qsmType === PortalQsmType.GroupTour) {
588
+ handleFlyInToggle(true);
589
+ }
590
+
591
+ try {
592
+ const config: TideClientConfig = {
593
+ host: context.tideConnection.host,
594
+ apiKey: context.tideConnection.apiKey
595
+ };
596
+
597
+ const selectedItem = results.find((r) => r.productId === selectedSearchResult.productId);
598
+ if (!selectedItem) {
599
+ // TODO: handle this case better, show an error message to the user
600
+ return;
601
+ }
602
+
603
+ const params = new URLSearchParams(location.search);
604
+ let entryId = getStringFromParams(params, 'entryId');
605
+
606
+ let requestRooms;
607
+ if (entry && entryId) {
608
+ requestRooms = getRequestRoomsFromEntry(entry.rooms);
609
+ } else {
610
+ const rooms = getRoomsFromParams(params, 'rooms');
611
+ requestRooms = getRequestRooms(rooms);
612
+ }
613
+
614
+ const detailsRequest: BookingPackageRequest<BookingPackageDetailsRequest> = {
615
+ officeId: 1,
616
+ payload: {
617
+ catalogueId: selectedItem.catalogueId,
618
+ rooms: requestRooms,
619
+ searchType: 0, // same as search
620
+ productCode: selectedItem.code,
621
+ fromDate: selectedItem.fromDate,
622
+ toDate: selectedItem.toDate,
623
+ includeFlights: context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight ? true : false,
624
+ includeHotels: true,
625
+ includePaxTypes: true,
626
+ checkExternalAvailability: true,
627
+ expectedPrice: selectedItem.price,
628
+ duration: null,
629
+ preNights: null,
630
+ postNights: null
631
+ },
632
+ agentId: context.agentId
633
+ };
634
+
635
+ if (entry && entryId) {
636
+ requestRooms = getRequestRoomsFromEntry(entry.rooms);
637
+ const detailsResponse = await details(config, detailsRequest);
638
+ console.log('Details:', detailsResponse);
639
+ dispatch(setBookingPackageDetails({ details: detailsResponse?.payload }));
640
+ } else {
641
+ // const detailsWLResponse = await detailsWL(config, detailsRequest);
642
+ // console.log('Details with entryLight:', detailsWLResponse);
643
+ // dispatch(setBookingPackageDetails({ details: detailsWLResponse?.payload?.bookingPackage }));
644
+ // dispatch(setEntry({ entry: detailsWLResponse?.payload?.entry }));
645
+
646
+ const detailsResponse = await details(config, detailsRequest);
647
+ dispatch(setBookingPackageDetails({ details: detailsResponse?.payload }));
648
+ setDetailsIsLoading(false);
649
+ }
650
+ } catch (err) {
651
+ console.error('Failed to fetch package details', err);
652
+ setDetailsIsLoading(false);
653
+ }
654
+ };
655
+
656
+ const fetchPackagingAccoSearchDetails = async () => {
657
+ if (!selectedPackagingAccoResultCode || !context) return;
658
+
659
+ if (context?.searchConfiguration.qsmType === PortalQsmType.Accommodation || context?.searchConfiguration.qsmType === PortalQsmType.GroupTour) {
660
+ handleFlyInToggle(true);
661
+ }
662
+
663
+ try {
664
+ const config: TideClientConfig = {
665
+ host: context.tideConnection.host,
666
+ apiKey: context.tideConnection.apiKey
667
+ };
668
+
669
+ console.log('selectedPackagingAccoResultCode', selectedPackagingAccoResultCode);
670
+ const selectedItem = packagingAccoResults.find((r) => r.code === selectedPackagingAccoResultCode);
671
+ console.log('Selected packaging acco item', selectedItem);
672
+ if (!selectedItem) {
673
+ // TODO: handle this case better, show an error message to the user
674
+ return;
675
+ }
676
+
677
+ const params = new URLSearchParams(location.search);
678
+ const rooms = getRoomsFromParams(params, 'rooms');
679
+ let tagId = getNumberFromParams(params, 'tagId');
680
+
681
+ let destinationAirport = getStringFromParams(params, 'destinationAirport');
682
+
683
+ let destinationId: number | null = null;
684
+ let destinationIsCountry = false;
685
+ let destinationIsRegion = false;
686
+ let destinationIsOord = false;
687
+ let destinationIsLocation = false;
688
+ let destinationCode: string | null = null;
689
+ let destinationIsAirport = false;
690
+
691
+ if (selectedItem.countryId) {
692
+ destinationId = selectedItem.countryId;
693
+ destinationIsCountry = true;
694
+ } else if (selectedItem.regionId) {
695
+ destinationId = selectedItem.regionId;
696
+ destinationIsRegion = true;
697
+ } else if (selectedItem.oordId) {
698
+ destinationId = selectedItem.oordId;
699
+ destinationIsOord = true;
700
+ } else if (selectedItem.locationId) {
701
+ destinationId = selectedItem.locationId;
702
+ destinationIsLocation = true;
703
+ } else if (destinationAirport) {
704
+ destinationCode = destinationAirport;
705
+ destinationIsAirport = true;
706
+ }
707
+
708
+ const detailSearchRequest: PackagingAccommodationRequest = {
709
+ officeId: 1,
710
+ portalId: context.portalId,
711
+ agentId: context.agentId,
712
+ catalogueId: context!.searchConfiguration.defaultCatalogueId ?? 0,
713
+ searchConfigurationId: context!.searchConfiguration.id,
714
+ vendorConfigurationId: selectedItem.vendorId,
715
+ language: context!.languageCode ?? 'en-GB',
716
+ serviceType: 3,
717
+ fromDate: selectedItem.fromDate,
718
+ toDate: selectedItem.toDate,
719
+ destination: {
720
+ id: Number(destinationId),
721
+ isCountry: destinationIsCountry,
722
+ isRegion: destinationIsRegion,
723
+ isOord: destinationIsOord,
724
+ isLocation: destinationIsLocation,
725
+ isAirport: destinationIsAirport,
726
+ code: destinationCode
727
+ } as PackagingDestination,
728
+ productCode: selectedItem.code ? selectedItem.code : '',
729
+ rooms: getPackagingRequestRooms(rooms),
730
+ tagIds: tagId ? [tagId] : []
731
+ };
732
+
733
+ const packageAccoSearchDetails = await searchPackagingAccommodations(config, detailSearchRequest);
734
+ console.log('Packaging Acco Search details', packageAccoSearchDetails);
735
+ dispatch(setPackagingAccoSearchDetails(packageAccoSearchDetails));
736
+ } catch (err) {
737
+ console.error('Failed to fetch package details', err);
738
+ }
739
+ };
740
+
741
+ if (selectedSearchResult) {
742
+ fetchDetails();
743
+ }
744
+ if (selectedPackagingAccoResultCode) {
745
+ fetchPackagingAccoSearchDetails();
746
+ }
747
+ }, [selectedSearchResult, selectedPackagingAccoResultCode]);
748
+
749
+ useEffect(() => {
750
+ if (context?.searchConfiguration.qsmType === PortalQsmType.Accommodation) {
751
+ const filteredPackageAccoResults = applyFiltersToPackageAccoResults(packagingAccoResults, filters, selectedSortType);
752
+ dispatch(setFilteredPackagingAccoResults(filteredPackageAccoResults));
753
+ } else {
754
+ const filteredResults = applyFilters(results, filters, selectedSortType);
755
+ dispatch(setFilteredResults(filteredResults));
756
+ }
757
+ }, [filters, results, packagingAccoResults, selectedSortType]);
758
+
759
+ return (
760
+ <div id="tide-booking" className="search__bg">
761
+ {context && (
762
+ <div className="search">
763
+ <div className="search__container">
764
+ {context.searchConfiguration.qsmType === PortalQsmType.Flight && (
765
+ <FlightSearchProvider tideConnection={context.tideConnection}>
766
+ <FlightResultsContainer isMobile={isMobile} />
767
+ <FlyIn
768
+ title="Select your fare"
769
+ srpType={context.searchConfiguration.qsmType}
770
+ isOpen={flyInIsOpen}
771
+ setIsOpen={handleFlyInToggle}
772
+ onPanelRef={(el) => (panelRef.current = el)}
773
+ detailsLoading={detailsIsLoading}
774
+ />
775
+ </FlightSearchProvider>
776
+ )}
777
+ {(context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight ||
778
+ context.searchConfiguration.qsmType === PortalQsmType.Accommodation ||
779
+ context.searchConfiguration.qsmType === PortalQsmType.GroupTour ||
780
+ context.searchConfiguration.qsmType === PortalQsmType.RoundTrip) && (
781
+ <>
782
+ {context.searchConfiguration.qsmType != PortalQsmType.AccommodationAndFlight && context.showFilters && (
783
+ <Filters
784
+ initialFilters={initialFilters}
785
+ filters={filters}
786
+ isOpen={filtersOpen}
787
+ handleSetIsOpen={() => setFiltersOpen(!filtersOpen)}
788
+ // handleApplyFilters={() => setSearchTrigger((prev) => prev + 1)}
789
+ isLoading={isLoading}
790
+ />
791
+ )}
792
+ {context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight && (
793
+ <Itinerary isOpen={itineraryOpen} handleSetIsOpen={() => setItineraryOpen(!itineraryOpen)} isLoading={isLoading} />
794
+ )}
795
+ {/* ---------------- Results ---------------- */}
796
+ <div className="search__results">
797
+ {isMobile && (
798
+ <div className="search__result-row">
799
+ <div className="search__results__actions">
800
+ {context.searchConfiguration.qsmType != PortalQsmType.AccommodationAndFlight && context.showFilters && (
801
+ <div className="cta cta--filter" onClick={() => setFiltersOpen(true)}>
802
+ <Icon name="ui-filter" className="mobile-filters-button__icon" height={16} />
803
+ {translations.SRP.FILTERS}
804
+ </div>
805
+ )}
806
+ {context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight && (
807
+ <div className="cta cta--filter" onClick={() => setItineraryOpen(true)}>
808
+ <Icon name="ui-calendar" className="mobile-filters-button__icon" height={16} />
809
+ {translations.SRP.SHOW_ITINERARY}
810
+ </div>
811
+ )}
812
+ </div>
813
+ {sortByTypes && sortByTypes.length > 0 && (
814
+ <ItemPicker
815
+ items={sortByTypes}
816
+ selection={selectedSortType?.label || undefined}
817
+ selectedSortByType={selectedSortType}
818
+ label={translations.SRP.SORTBY}
819
+ placeholder={translations.SRP.SORTBY}
820
+ classModifier="travel-class-picker__items"
821
+ valueFormatter={(value, direction) => getSortingName(translations, findSortByType(sortByTypes, value, direction ?? 'asc'))}
822
+ onPick={(newSortKey, direction) => handleSortChange(newSortKey, direction)}
823
+ />
824
+ )}
825
+ </div>
826
+ )}
827
+ <div className="search__result-row">
828
+ <span className="search__result-row-text">
829
+ {!isLoading && (
830
+ <>
831
+ {((context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight &&
832
+ context.searchConfiguration.enableManualPackaging) ||
833
+ context.searchConfiguration.qsmType === PortalQsmType.Accommodation) &&
834
+ filteredPackagingAccoResults?.length &&
835
+ filteredPackagingAccoResults?.length}
836
+ {context.searchConfiguration.qsmType !== PortalQsmType.Accommodation && filteredResults?.length && filteredResults.length}
837
+ &nbsp;{translations.SRP.TOTAL_RESULTS_LABEL}
838
+ </>
839
+ )}
840
+ </span>
841
+ {!isMobile && sortByTypes && sortByTypes.length > 0 && (
842
+ <div className="search__result-row-filter">
843
+ <ItemPicker
844
+ items={sortByTypes}
845
+ selection={selectedSortType?.label || undefined}
846
+ selectedSortByType={selectedSortType}
847
+ label={translations.SRP.SORTBY}
848
+ placeholder={translations.SRP.SORTBY}
849
+ classModifier="travel-class-picker__items"
850
+ valueFormatter={(value, direction) => getSortingName(translations, findSortByType(sortByTypes, value, direction ?? 'asc'))}
851
+ onPick={(newSortKey, direction) => handleSortChange(newSortKey, direction)}
852
+ />
853
+ </div>
854
+ )}
855
+ </div>
856
+
857
+ <div className="search__results__wrapper">
858
+ {context.showTabViews && <TabViews />}
859
+
860
+ {context.showRoundTripResults && context.showMockup && <RoundTripResults />}
861
+
862
+ {context.searchConfiguration.qsmType === PortalQsmType.GroupTour && <GroupTourResults isLoading={isLoading} />}
863
+
864
+ {context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight &&
865
+ context.showFlightResults &&
866
+ bookingPackageDetails?.outwardFlights && <FlightResults flights={bookingPackageDetails?.outwardFlights} isDeparture={true} />}
867
+
868
+ {context.showHotelAccommodationResults && <HotelAccommodationResults isLoading={isLoading} />}
869
+
870
+ {context.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight &&
871
+ context.showFlightResults &&
872
+ bookingPackageDetails?.returnFlights && <FlightResults flights={bookingPackageDetails?.returnFlights} isDeparture={false} />}
873
+ </div>
874
+ </div>
875
+ {/* <button onClick={() => handleFlyInToggle(!flyInIsOpen)}>Toggle FlyIn</button> */}
876
+ <FlyIn
877
+ title={`${translations.SRP.SELECT} ${translations.SRP.ACCOMMODATION}`}
878
+ srpType={context.searchConfiguration.qsmType}
879
+ isOpen={flyInIsOpen}
880
+ setIsOpen={handleFlyInToggle}
881
+ onPanelRef={(el) => (panelRef.current = el)}
882
+ detailsLoading={detailsIsLoading}
883
+ />
884
+ </>
885
+ )}
886
+ </div>
887
+ </div>
888
+ )}
889
+ </div>
890
+ );
891
+ };
892
+
893
+ export default SearchResultsContainer;