@qite/tide-booking-component 1.4.95 → 1.4.97

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 (453) hide show
  1. package/README.md +24 -24
  2. package/build/build-cjs/index.js +48813 -29709
  3. package/build/build-cjs/src/booking-product/components/age-select.d.ts +3 -3
  4. package/build/build-cjs/src/booking-product/components/amount-input.d.ts +5 -5
  5. package/build/build-cjs/src/booking-product/components/date-range-picker/calendar-day.d.ts +8 -8
  6. package/build/build-cjs/src/booking-product/components/date-range-picker/calendar.d.ts +14 -14
  7. package/build/build-cjs/src/booking-product/components/date-range-picker/index.d.ts +16 -19
  8. package/build/build-cjs/src/booking-product/components/dates.d.ts +8 -8
  9. package/build/build-cjs/src/booking-product/components/footer.d.ts +5 -5
  10. package/build/build-cjs/src/booking-product/components/header.d.ts +6 -6
  11. package/build/build-cjs/src/booking-product/components/icon.d.ts +5 -5
  12. package/build/build-cjs/src/booking-product/components/list-view.d.ts +2 -2
  13. package/build/build-cjs/src/booking-product/components/product.d.ts +4 -4
  14. package/build/build-cjs/src/booking-product/components/rating.d.ts +1 -1
  15. package/build/build-cjs/src/booking-product/components/rooms.d.ts +4 -4
  16. package/build/build-cjs/src/booking-product/constants.d.ts +1 -1
  17. package/build/build-cjs/src/booking-product/index.d.ts +4 -4
  18. package/build/build-cjs/src/booking-product/settings-context.d.ts +1 -2
  19. package/build/build-cjs/src/booking-product/types.d.ts +21 -21
  20. package/build/build-cjs/src/booking-product/utils/api.d.ts +11 -2
  21. package/build/build-cjs/src/booking-product/utils/price.d.ts +10 -1
  22. package/build/build-cjs/src/booking-wizard/api-settings-slice.d.ts +3 -2
  23. package/build/build-cjs/src/booking-wizard/components/icon.d.ts +5 -5
  24. package/build/build-cjs/src/booking-wizard/components/labeled-input.d.ts +13 -13
  25. package/build/build-cjs/src/booking-wizard/components/labeled-select.d.ts +16 -16
  26. package/build/build-cjs/src/booking-wizard/components/message.d.ts +4 -4
  27. package/build/build-cjs/src/booking-wizard/components/multi-range-filter.d.ts +6 -6
  28. package/build/build-cjs/src/booking-wizard/components/phone-input.d.ts +11 -11
  29. package/build/build-cjs/src/booking-wizard/components/print-offer-button.d.ts +11 -11
  30. package/build/build-cjs/src/booking-wizard/components/product-card.d.ts +3 -3
  31. package/build/build-cjs/src/booking-wizard/components/step-indicator.d.ts +1 -1
  32. package/build/build-cjs/src/booking-wizard/components/step-route.d.ts +3 -3
  33. package/build/build-cjs/src/booking-wizard/features/booking/api.d.ts +26 -7
  34. package/build/build-cjs/src/booking-wizard/features/booking/booking-self-contained.d.ts +3 -3
  35. package/build/build-cjs/src/booking-wizard/features/booking/booking-slice.d.ts +102 -43
  36. package/build/build-cjs/src/booking-wizard/features/booking/booking.d.ts +3 -3
  37. package/build/build-cjs/src/booking-wizard/features/booking/constants.d.ts +8 -1
  38. package/build/build-cjs/src/booking-wizard/features/booking/selectors.d.ts +644 -479
  39. package/build/build-cjs/src/booking-wizard/features/confirmation/confirmation.d.ts +1 -2
  40. package/build/build-cjs/src/booking-wizard/features/error/error.d.ts +1 -2
  41. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-filter.d.ts +3 -3
  42. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-option-flight.d.ts +2 -2
  43. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-option.d.ts +4 -4
  44. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-utils.d.ts +9 -2
  45. package/build/build-cjs/src/booking-wizard/features/flight-options/index.d.ts +1 -2
  46. package/build/build-cjs/src/booking-wizard/features/price-details/price-details-api.d.ts +6 -1
  47. package/build/build-cjs/src/booking-wizard/features/price-details/price-details-slice.d.ts +15 -10
  48. package/build/build-cjs/src/booking-wizard/features/price-details/selectors.d.ts +302 -287
  49. package/build/build-cjs/src/booking-wizard/features/product-options/none-option.d.ts +3 -3
  50. package/build/build-cjs/src/booking-wizard/features/product-options/option-booking-airline-group.d.ts +2 -2
  51. package/build/build-cjs/src/booking-wizard/features/product-options/option-booking-group.d.ts +6 -6
  52. package/build/build-cjs/src/booking-wizard/features/product-options/option-item.d.ts +5 -5
  53. package/build/build-cjs/src/booking-wizard/features/product-options/option-pax-card.d.ts +4 -4
  54. package/build/build-cjs/src/booking-wizard/features/product-options/option-pax-group.d.ts +7 -7
  55. package/build/build-cjs/src/booking-wizard/features/product-options/option-room.d.ts +5 -5
  56. package/build/build-cjs/src/booking-wizard/features/product-options/option-unit-group.d.ts +7 -7
  57. package/build/build-cjs/src/booking-wizard/features/product-options/option-units-card.d.ts +3 -3
  58. package/build/build-cjs/src/booking-wizard/features/product-options/options-form.d.ts +1 -2
  59. package/build/build-cjs/src/booking-wizard/features/room-options/index.d.ts +1 -2
  60. package/build/build-cjs/src/booking-wizard/features/room-options/room-utils.d.ts +19 -6
  61. package/build/build-cjs/src/booking-wizard/features/room-options/room.d.ts +6 -6
  62. package/build/build-cjs/src/booking-wizard/features/room-options/traveler-rooms.d.ts +3 -3
  63. package/build/build-cjs/src/booking-wizard/features/sidebar/index.d.ts +2 -2
  64. package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar-flight.d.ts +2 -2
  65. package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar-util.d.ts +4 -2
  66. package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar.d.ts +24 -24
  67. package/build/build-cjs/src/booking-wizard/features/summary/summary-booking-option-pax.d.ts +1 -1
  68. package/build/build-cjs/src/booking-wizard/features/summary/summary-booking-option-unit.d.ts +1 -1
  69. package/build/build-cjs/src/booking-wizard/features/summary/summary-flight.d.ts +2 -2
  70. package/build/build-cjs/src/booking-wizard/features/summary/summary-per-booking-option-group.d.ts +1 -1
  71. package/build/build-cjs/src/booking-wizard/features/summary/summary-per-pax-option-group.d.ts +1 -1
  72. package/build/build-cjs/src/booking-wizard/features/summary/summary-per-unit-option-group.d.ts +1 -1
  73. package/build/build-cjs/src/booking-wizard/features/summary/summary-slice.d.ts +3 -3
  74. package/build/build-cjs/src/booking-wizard/features/summary/summary.d.ts +1 -2
  75. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +75 -75
  76. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form-util.d.ts +4 -4
  77. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form.d.ts +1 -2
  78. package/build/build-cjs/src/booking-wizard/features/travelers-form/type-ahead-input.d.ts +11 -11
  79. package/build/build-cjs/src/booking-wizard/features/travelers-form/validate-form.d.ts +8 -1
  80. package/build/build-cjs/src/booking-wizard/index.d.ts +6 -6
  81. package/build/build-cjs/src/booking-wizard/settings-context.d.ts +1 -2
  82. package/build/build-cjs/src/booking-wizard/store.d.ts +40 -22
  83. package/build/build-cjs/src/booking-wizard/types.d.ts +240 -240
  84. package/build/build-cjs/src/booking-wizard/use-offer-printer.d.ts +8 -8
  85. package/build/build-cjs/src/content/components/LanguageSwitcher.d.ts +5 -5
  86. package/build/build-cjs/src/content/components/accordion.d.ts +4 -4
  87. package/build/build-cjs/src/content/components/breadcrumb.d.ts +7 -7
  88. package/build/build-cjs/src/content/components/faq.d.ts +4 -4
  89. package/build/build-cjs/src/content/components/gallery.d.ts +6 -6
  90. package/build/build-cjs/src/content/components/icon.d.ts +5 -5
  91. package/build/build-cjs/src/content/components/image-with-text.d.ts +18 -18
  92. package/build/build-cjs/src/content/components/slider.d.ts +5 -5
  93. package/build/build-cjs/src/content/featured-trips/types.d.ts +8 -8
  94. package/build/build-cjs/src/content/features/content-page/content-page-self-contained.d.ts +1 -1
  95. package/build/build-cjs/src/content/footer/types.d.ts +17 -17
  96. package/build/build-cjs/src/content/header/types.d.ts +23 -20
  97. package/build/build-cjs/src/content/image-card-grid/types.d.ts +8 -8
  98. package/build/build-cjs/src/content/image-with-text-section/types.d.ts +15 -15
  99. package/build/build-cjs/src/content/login/login-services.d.ts +6 -1
  100. package/build/build-cjs/src/content/login/types.d.ts +19 -19
  101. package/build/build-cjs/src/content/navbar/placeholderData.d.ts +2 -2
  102. package/build/build-cjs/src/content/navbar/types.d.ts +22 -22
  103. package/build/build-cjs/src/index.d.ts +17 -1
  104. package/build/build-cjs/src/qsm/components/date-range-picker/calendar-day.d.ts +7 -7
  105. package/build/build-cjs/src/qsm/components/date-range-picker/calendar.d.ts +18 -18
  106. package/build/build-cjs/src/qsm/components/date-range-picker/index.d.ts +5 -5
  107. package/build/build-cjs/src/qsm/components/double-search-input-group/index.d.ts +2 -2
  108. package/build/build-cjs/src/qsm/components/icon.d.ts +5 -5
  109. package/build/build-cjs/src/qsm/components/item-picker/index.d.ts +7 -7
  110. package/build/build-cjs/src/qsm/components/search-input/index.d.ts +9 -9
  111. package/build/build-cjs/src/qsm/components/search-input-group/index.d.ts +7 -7
  112. package/build/build-cjs/src/qsm/index.d.ts +1 -1
  113. package/build/build-cjs/src/qsm/store/qsm-slice.d.ts +110 -58
  114. package/build/build-cjs/src/qsm/store/qsm-store.d.ts +20 -7
  115. package/build/build-cjs/src/qsm/types.d.ts +59 -59
  116. package/build/build-cjs/src/search-results/components/filters/filters.d.ts +5 -5
  117. package/build/build-cjs/src/search-results/components/filters/flight-filters.d.ts +3 -3
  118. package/build/build-cjs/src/search-results/components/flight/flight-banner.d.ts +2 -2
  119. package/build/build-cjs/src/search-results/components/flight/flight-card.d.ts +1 -1
  120. package/build/build-cjs/src/search-results/components/flight/flight-leg.d.ts +1 -1
  121. package/build/build-cjs/src/search-results/components/flight/flight-path.d.ts +1 -1
  122. package/build/build-cjs/src/search-results/components/flight/flight-results.d.ts +2 -2
  123. package/build/build-cjs/src/search-results/components/flight/flight-search-context/index.d.ts +29 -29
  124. package/build/build-cjs/src/search-results/components/flight/flight-selection/independent-flight-option.d.ts +5 -5
  125. package/build/build-cjs/src/search-results/components/flight/flight-selection/independent-flight-selection.d.ts +1 -1
  126. package/build/build-cjs/src/search-results/components/flight/flight-selection/index.d.ts +2 -2
  127. package/build/build-cjs/src/search-results/components/flight/flight-selection/paired-flight-option.d.ts +1 -1
  128. package/build/build-cjs/src/search-results/components/flight/flight-selection/paired-flight-selection.d.ts +1 -1
  129. package/build/build-cjs/src/search-results/components/group-tour/group-tour-card.d.ts +3 -3
  130. package/build/build-cjs/src/search-results/components/group-tour/group-tour-results.d.ts +1 -1
  131. package/build/build-cjs/src/search-results/components/hotel/hotel-accommodation-results.d.ts +1 -1
  132. package/build/build-cjs/src/search-results/components/hotel/hotel-card.d.ts +2 -2
  133. package/build/build-cjs/src/search-results/components/icon.d.ts +6 -6
  134. package/build/build-cjs/src/search-results/components/item-picker/index.d.ts +8 -8
  135. package/build/build-cjs/src/search-results/components/itinerary/index.d.ts +3 -3
  136. package/build/build-cjs/src/search-results/components/multi-range-filter.d.ts +6 -6
  137. package/build/build-cjs/src/search-results/components/round-trip/round-trip-results.d.ts +1 -2
  138. package/build/build-cjs/src/search-results/components/search-results-container/flight-search-results.d.ts +1 -1
  139. package/build/build-cjs/src/search-results/components/tab-views/index.d.ts +1 -2
  140. package/build/build-cjs/src/search-results/features/flights/flight-search-results-self-contained.d.ts +1 -2
  141. package/build/build-cjs/src/search-results/features/hotels/hotel-flight-search-results-self-contained.d.ts +1 -2
  142. package/build/build-cjs/src/search-results/features/hotels/hotel-search-results-self-contained.d.ts +1 -2
  143. package/build/build-cjs/src/search-results/features/roundtrips/roundtrip-search-results-self-contained.d.ts +1 -2
  144. package/build/build-cjs/src/search-results/index.d.ts +1 -1
  145. package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +63 -26
  146. package/build/build-cjs/src/search-results/store/search-results-store.d.ts +20 -7
  147. package/build/build-cjs/src/search-results/types.d.ts +104 -104
  148. package/build/build-cjs/src/search-results/utils/flight-utils.d.ts +6 -1
  149. package/build/build-cjs/src/search-results/utils/search-results-utils.d.ts +10 -2
  150. package/build/build-cjs/src/shared/components/flyin/accommodation-flyin.d.ts +3 -3
  151. package/build/build-cjs/src/shared/components/flyin/flights-flyin.d.ts +2 -2
  152. package/build/build-cjs/src/shared/components/flyin/flyin.d.ts +7 -7
  153. package/build/build-cjs/src/shared/components/flyin/group-tour-flyin.d.ts +3 -3
  154. package/build/build-cjs/src/shared/components/icon.d.ts +5 -5
  155. package/build/build-cjs/src/shared/components/loader.d.ts +1 -1
  156. package/build/build-cjs/src/shared/types.d.ts +9 -9
  157. package/build/build-cjs/src/shared/utils/localization-util.d.ts +395 -396
  158. package/build/build-esm/index.js +48531 -29650
  159. package/build/build-esm/src/booking-product/components/age-select.d.ts +3 -3
  160. package/build/build-esm/src/booking-product/components/amount-input.d.ts +5 -5
  161. package/build/build-esm/src/booking-product/components/date-range-picker/calendar-day.d.ts +8 -8
  162. package/build/build-esm/src/booking-product/components/date-range-picker/calendar.d.ts +14 -14
  163. package/build/build-esm/src/booking-product/components/date-range-picker/index.d.ts +16 -19
  164. package/build/build-esm/src/booking-product/components/dates.d.ts +8 -8
  165. package/build/build-esm/src/booking-product/components/footer.d.ts +5 -5
  166. package/build/build-esm/src/booking-product/components/header.d.ts +6 -6
  167. package/build/build-esm/src/booking-product/components/icon.d.ts +5 -5
  168. package/build/build-esm/src/booking-product/components/list-view.d.ts +2 -2
  169. package/build/build-esm/src/booking-product/components/product.d.ts +4 -4
  170. package/build/build-esm/src/booking-product/components/rating.d.ts +1 -1
  171. package/build/build-esm/src/booking-product/components/rooms.d.ts +4 -4
  172. package/build/build-esm/src/booking-product/constants.d.ts +1 -1
  173. package/build/build-esm/src/booking-product/index.d.ts +4 -4
  174. package/build/build-esm/src/booking-product/settings-context.d.ts +1 -2
  175. package/build/build-esm/src/booking-product/types.d.ts +21 -21
  176. package/build/build-esm/src/booking-product/utils/api.d.ts +11 -2
  177. package/build/build-esm/src/booking-product/utils/price.d.ts +10 -1
  178. package/build/build-esm/src/booking-wizard/api-settings-slice.d.ts +3 -2
  179. package/build/build-esm/src/booking-wizard/components/icon.d.ts +5 -5
  180. package/build/build-esm/src/booking-wizard/components/labeled-input.d.ts +13 -13
  181. package/build/build-esm/src/booking-wizard/components/labeled-select.d.ts +16 -16
  182. package/build/build-esm/src/booking-wizard/components/message.d.ts +4 -4
  183. package/build/build-esm/src/booking-wizard/components/multi-range-filter.d.ts +6 -6
  184. package/build/build-esm/src/booking-wizard/components/phone-input.d.ts +11 -11
  185. package/build/build-esm/src/booking-wizard/components/print-offer-button.d.ts +11 -11
  186. package/build/build-esm/src/booking-wizard/components/product-card.d.ts +3 -3
  187. package/build/build-esm/src/booking-wizard/components/step-indicator.d.ts +1 -1
  188. package/build/build-esm/src/booking-wizard/components/step-route.d.ts +3 -3
  189. package/build/build-esm/src/booking-wizard/features/booking/api.d.ts +26 -7
  190. package/build/build-esm/src/booking-wizard/features/booking/booking-self-contained.d.ts +3 -3
  191. package/build/build-esm/src/booking-wizard/features/booking/booking-slice.d.ts +102 -43
  192. package/build/build-esm/src/booking-wizard/features/booking/booking.d.ts +3 -3
  193. package/build/build-esm/src/booking-wizard/features/booking/constants.d.ts +8 -1
  194. package/build/build-esm/src/booking-wizard/features/booking/selectors.d.ts +644 -479
  195. package/build/build-esm/src/booking-wizard/features/confirmation/confirmation.d.ts +1 -2
  196. package/build/build-esm/src/booking-wizard/features/error/error.d.ts +1 -2
  197. package/build/build-esm/src/booking-wizard/features/flight-options/flight-filter.d.ts +3 -3
  198. package/build/build-esm/src/booking-wizard/features/flight-options/flight-option-flight.d.ts +2 -2
  199. package/build/build-esm/src/booking-wizard/features/flight-options/flight-option.d.ts +4 -4
  200. package/build/build-esm/src/booking-wizard/features/flight-options/flight-utils.d.ts +9 -2
  201. package/build/build-esm/src/booking-wizard/features/flight-options/index.d.ts +1 -2
  202. package/build/build-esm/src/booking-wizard/features/price-details/price-details-api.d.ts +6 -1
  203. package/build/build-esm/src/booking-wizard/features/price-details/price-details-slice.d.ts +15 -10
  204. package/build/build-esm/src/booking-wizard/features/price-details/selectors.d.ts +302 -287
  205. package/build/build-esm/src/booking-wizard/features/product-options/none-option.d.ts +3 -3
  206. package/build/build-esm/src/booking-wizard/features/product-options/option-booking-airline-group.d.ts +2 -2
  207. package/build/build-esm/src/booking-wizard/features/product-options/option-booking-group.d.ts +6 -6
  208. package/build/build-esm/src/booking-wizard/features/product-options/option-item.d.ts +5 -5
  209. package/build/build-esm/src/booking-wizard/features/product-options/option-pax-card.d.ts +4 -4
  210. package/build/build-esm/src/booking-wizard/features/product-options/option-pax-group.d.ts +7 -7
  211. package/build/build-esm/src/booking-wizard/features/product-options/option-room.d.ts +5 -5
  212. package/build/build-esm/src/booking-wizard/features/product-options/option-unit-group.d.ts +7 -7
  213. package/build/build-esm/src/booking-wizard/features/product-options/option-units-card.d.ts +3 -3
  214. package/build/build-esm/src/booking-wizard/features/product-options/options-form.d.ts +1 -2
  215. package/build/build-esm/src/booking-wizard/features/room-options/index.d.ts +1 -2
  216. package/build/build-esm/src/booking-wizard/features/room-options/room-utils.d.ts +19 -6
  217. package/build/build-esm/src/booking-wizard/features/room-options/room.d.ts +6 -6
  218. package/build/build-esm/src/booking-wizard/features/room-options/traveler-rooms.d.ts +3 -3
  219. package/build/build-esm/src/booking-wizard/features/sidebar/index.d.ts +2 -2
  220. package/build/build-esm/src/booking-wizard/features/sidebar/sidebar-flight.d.ts +2 -2
  221. package/build/build-esm/src/booking-wizard/features/sidebar/sidebar-util.d.ts +4 -2
  222. package/build/build-esm/src/booking-wizard/features/sidebar/sidebar.d.ts +24 -24
  223. package/build/build-esm/src/booking-wizard/features/summary/summary-booking-option-pax.d.ts +1 -1
  224. package/build/build-esm/src/booking-wizard/features/summary/summary-booking-option-unit.d.ts +1 -1
  225. package/build/build-esm/src/booking-wizard/features/summary/summary-flight.d.ts +2 -2
  226. package/build/build-esm/src/booking-wizard/features/summary/summary-per-booking-option-group.d.ts +1 -1
  227. package/build/build-esm/src/booking-wizard/features/summary/summary-per-pax-option-group.d.ts +1 -1
  228. package/build/build-esm/src/booking-wizard/features/summary/summary-per-unit-option-group.d.ts +1 -1
  229. package/build/build-esm/src/booking-wizard/features/summary/summary-slice.d.ts +3 -3
  230. package/build/build-esm/src/booking-wizard/features/summary/summary.d.ts +1 -2
  231. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +75 -75
  232. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form-util.d.ts +4 -4
  233. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form.d.ts +1 -2
  234. package/build/build-esm/src/booking-wizard/features/travelers-form/type-ahead-input.d.ts +11 -11
  235. package/build/build-esm/src/booking-wizard/features/travelers-form/validate-form.d.ts +8 -1
  236. package/build/build-esm/src/booking-wizard/index.d.ts +6 -6
  237. package/build/build-esm/src/booking-wizard/settings-context.d.ts +1 -2
  238. package/build/build-esm/src/booking-wizard/store.d.ts +40 -22
  239. package/build/build-esm/src/booking-wizard/types.d.ts +240 -240
  240. package/build/build-esm/src/booking-wizard/use-offer-printer.d.ts +8 -8
  241. package/build/build-esm/src/content/components/LanguageSwitcher.d.ts +5 -5
  242. package/build/build-esm/src/content/components/accordion.d.ts +4 -4
  243. package/build/build-esm/src/content/components/breadcrumb.d.ts +7 -7
  244. package/build/build-esm/src/content/components/faq.d.ts +4 -4
  245. package/build/build-esm/src/content/components/gallery.d.ts +6 -6
  246. package/build/build-esm/src/content/components/icon.d.ts +5 -5
  247. package/build/build-esm/src/content/components/image-with-text.d.ts +18 -18
  248. package/build/build-esm/src/content/components/slider.d.ts +5 -5
  249. package/build/build-esm/src/content/featured-trips/types.d.ts +8 -8
  250. package/build/build-esm/src/content/features/content-page/content-page-self-contained.d.ts +1 -1
  251. package/build/build-esm/src/content/footer/types.d.ts +17 -17
  252. package/build/build-esm/src/content/header/types.d.ts +23 -20
  253. package/build/build-esm/src/content/image-card-grid/types.d.ts +8 -8
  254. package/build/build-esm/src/content/image-with-text-section/types.d.ts +15 -15
  255. package/build/build-esm/src/content/login/login-services.d.ts +6 -1
  256. package/build/build-esm/src/content/login/types.d.ts +19 -19
  257. package/build/build-esm/src/content/navbar/placeholderData.d.ts +2 -2
  258. package/build/build-esm/src/content/navbar/types.d.ts +22 -22
  259. package/build/build-esm/src/index.d.ts +17 -1
  260. package/build/build-esm/src/qsm/components/date-range-picker/calendar-day.d.ts +7 -7
  261. package/build/build-esm/src/qsm/components/date-range-picker/calendar.d.ts +18 -18
  262. package/build/build-esm/src/qsm/components/date-range-picker/index.d.ts +5 -5
  263. package/build/build-esm/src/qsm/components/double-search-input-group/index.d.ts +2 -2
  264. package/build/build-esm/src/qsm/components/icon.d.ts +5 -5
  265. package/build/build-esm/src/qsm/components/item-picker/index.d.ts +7 -7
  266. package/build/build-esm/src/qsm/components/search-input/index.d.ts +9 -9
  267. package/build/build-esm/src/qsm/components/search-input-group/index.d.ts +7 -7
  268. package/build/build-esm/src/qsm/index.d.ts +1 -1
  269. package/build/build-esm/src/qsm/store/qsm-slice.d.ts +110 -58
  270. package/build/build-esm/src/qsm/store/qsm-store.d.ts +20 -7
  271. package/build/build-esm/src/qsm/types.d.ts +59 -59
  272. package/build/build-esm/src/search-results/components/filters/filters.d.ts +5 -5
  273. package/build/build-esm/src/search-results/components/filters/flight-filters.d.ts +3 -3
  274. package/build/build-esm/src/search-results/components/flight/flight-banner.d.ts +2 -2
  275. package/build/build-esm/src/search-results/components/flight/flight-card.d.ts +1 -1
  276. package/build/build-esm/src/search-results/components/flight/flight-leg.d.ts +1 -1
  277. package/build/build-esm/src/search-results/components/flight/flight-path.d.ts +1 -1
  278. package/build/build-esm/src/search-results/components/flight/flight-results.d.ts +2 -2
  279. package/build/build-esm/src/search-results/components/flight/flight-search-context/index.d.ts +29 -29
  280. package/build/build-esm/src/search-results/components/flight/flight-selection/independent-flight-option.d.ts +5 -5
  281. package/build/build-esm/src/search-results/components/flight/flight-selection/independent-flight-selection.d.ts +1 -1
  282. package/build/build-esm/src/search-results/components/flight/flight-selection/index.d.ts +2 -2
  283. package/build/build-esm/src/search-results/components/flight/flight-selection/paired-flight-option.d.ts +1 -1
  284. package/build/build-esm/src/search-results/components/flight/flight-selection/paired-flight-selection.d.ts +1 -1
  285. package/build/build-esm/src/search-results/components/group-tour/group-tour-card.d.ts +3 -3
  286. package/build/build-esm/src/search-results/components/group-tour/group-tour-results.d.ts +1 -1
  287. package/build/build-esm/src/search-results/components/hotel/hotel-accommodation-results.d.ts +1 -1
  288. package/build/build-esm/src/search-results/components/hotel/hotel-card.d.ts +2 -2
  289. package/build/build-esm/src/search-results/components/icon.d.ts +6 -6
  290. package/build/build-esm/src/search-results/components/item-picker/index.d.ts +8 -8
  291. package/build/build-esm/src/search-results/components/itinerary/index.d.ts +3 -3
  292. package/build/build-esm/src/search-results/components/multi-range-filter.d.ts +6 -6
  293. package/build/build-esm/src/search-results/components/round-trip/round-trip-results.d.ts +1 -2
  294. package/build/build-esm/src/search-results/components/search-results-container/flight-search-results.d.ts +1 -1
  295. package/build/build-esm/src/search-results/components/tab-views/index.d.ts +1 -2
  296. package/build/build-esm/src/search-results/features/flights/flight-search-results-self-contained.d.ts +1 -2
  297. package/build/build-esm/src/search-results/features/hotels/hotel-flight-search-results-self-contained.d.ts +1 -2
  298. package/build/build-esm/src/search-results/features/hotels/hotel-search-results-self-contained.d.ts +1 -2
  299. package/build/build-esm/src/search-results/features/roundtrips/roundtrip-search-results-self-contained.d.ts +1 -2
  300. package/build/build-esm/src/search-results/index.d.ts +1 -1
  301. package/build/build-esm/src/search-results/store/search-results-slice.d.ts +63 -26
  302. package/build/build-esm/src/search-results/store/search-results-store.d.ts +20 -7
  303. package/build/build-esm/src/search-results/types.d.ts +104 -104
  304. package/build/build-esm/src/search-results/utils/flight-utils.d.ts +6 -1
  305. package/build/build-esm/src/search-results/utils/search-results-utils.d.ts +10 -2
  306. package/build/build-esm/src/shared/components/flyin/accommodation-flyin.d.ts +3 -3
  307. package/build/build-esm/src/shared/components/flyin/flights-flyin.d.ts +2 -2
  308. package/build/build-esm/src/shared/components/flyin/flyin.d.ts +7 -7
  309. package/build/build-esm/src/shared/components/flyin/group-tour-flyin.d.ts +3 -3
  310. package/build/build-esm/src/shared/components/icon.d.ts +5 -5
  311. package/build/build-esm/src/shared/components/loader.d.ts +1 -1
  312. package/build/build-esm/src/shared/types.d.ts +9 -9
  313. package/build/build-esm/src/shared/utils/localization-util.d.ts +395 -396
  314. package/package.json +83 -83
  315. package/rollup.config.js +16 -16
  316. package/src/booking-product/components/date-range-picker/calendar-day.tsx +46 -46
  317. package/src/booking-product/components/date-range-picker/index.tsx +185 -185
  318. package/src/booking-product/components/dates.tsx +153 -153
  319. package/src/booking-product/components/product.tsx +379 -379
  320. package/src/booking-wizard/components/step-indicator.tsx +57 -57
  321. package/src/booking-wizard/components/step-route.tsx +26 -26
  322. package/src/booking-wizard/features/booking/api.ts +44 -44
  323. package/src/booking-wizard/features/booking/booking-self-contained.tsx +318 -318
  324. package/src/booking-wizard/features/booking/booking-slice.ts +633 -633
  325. package/src/booking-wizard/features/booking/booking.tsx +342 -342
  326. package/src/booking-wizard/features/booking/constants.ts +16 -16
  327. package/src/booking-wizard/features/booking/selectors.ts +411 -411
  328. package/src/booking-wizard/features/confirmation/confirmation.tsx +90 -90
  329. package/src/booking-wizard/features/error/error.tsx +71 -71
  330. package/src/booking-wizard/features/flight-options/index.tsx +166 -166
  331. package/src/booking-wizard/features/price-details/price-details-slice.ts +79 -79
  332. package/src/booking-wizard/features/price-details/selectors.ts +118 -118
  333. package/src/booking-wizard/features/product-options/option-units-card.tsx +148 -148
  334. package/src/booking-wizard/features/product-options/options-form.tsx +382 -382
  335. package/src/booking-wizard/features/room-options/index.tsx +132 -132
  336. package/src/booking-wizard/features/sidebar/index.tsx +83 -83
  337. package/src/booking-wizard/features/sidebar/sidebar-util.ts +147 -147
  338. package/src/booking-wizard/features/sidebar/sidebar.tsx +344 -332
  339. package/src/booking-wizard/features/summary/summary.tsx +562 -562
  340. package/src/booking-wizard/features/travelers-form/controls/gender-control.tsx +60 -60
  341. package/src/booking-wizard/features/travelers-form/travelers-form.tsx +1101 -1101
  342. package/src/booking-wizard/settings-context.ts +64 -64
  343. package/src/booking-wizard/types.ts +332 -332
  344. package/src/content/components/breadcrumb.tsx +67 -67
  345. package/src/content/components/faq.tsx +42 -42
  346. package/src/content/components/gallery.tsx +153 -153
  347. package/src/content/components/icon.tsx +695 -695
  348. package/src/content/components/image-with-text.tsx +120 -120
  349. package/src/content/components/login.tsx +162 -162
  350. package/src/content/components/slider.tsx +237 -237
  351. package/src/content/featured-trips/featured-trip-card.tsx +48 -48
  352. package/src/content/featured-trips/index.tsx +19 -19
  353. package/src/content/featured-trips/types.ts +13 -13
  354. package/src/content/features/content-page/content-page-self-contained.tsx +895 -895
  355. package/src/content/footer/index.tsx +159 -159
  356. package/src/content/footer/types.ts +36 -36
  357. package/src/content/image-card-grid/index.tsx +34 -34
  358. package/src/content/image-card-grid/types.ts +13 -13
  359. package/src/content/image-with-text-section/card.tsx +58 -58
  360. package/src/content/image-with-text-section/index.tsx +22 -22
  361. package/src/content/image-with-text-section/types.ts +20 -20
  362. package/src/content/login/confirm-component.tsx +149 -149
  363. package/src/content/login/index.tsx +70 -70
  364. package/src/content/login/login-component.tsx +159 -159
  365. package/src/content/login/login-services.ts +109 -109
  366. package/src/content/login/reset-password-component.tsx +191 -191
  367. package/src/content/login/types.ts +29 -29
  368. package/src/content/navbar/index.tsx +354 -354
  369. package/src/content/navbar/placeholderData.tsx +173 -173
  370. package/src/content/navbar/types.ts +43 -43
  371. package/src/index.ts +44 -44
  372. package/src/qsm/components/QSMContainer/qsm-container.tsx +512 -512
  373. package/src/qsm/components/double-search-input-group/index.tsx +78 -78
  374. package/src/qsm/components/icon.tsx +354 -354
  375. package/src/qsm/components/item-picker/index.tsx +69 -69
  376. package/src/qsm/components/mobile-filter-modal/index.tsx +307 -307
  377. package/src/qsm/components/search-input/index.tsx +91 -91
  378. package/src/qsm/components/search-input-group/index.tsx +199 -199
  379. package/src/qsm/components/travel-class-picker/index.tsx +28 -28
  380. package/src/qsm/components/travel-input/index.tsx +243 -243
  381. package/src/qsm/components/travel-input-group/index.tsx +114 -114
  382. package/src/qsm/components/travel-nationality-picker/index.tsx +28 -28
  383. package/src/qsm/components/travel-type-picker/index.tsx +28 -28
  384. package/src/qsm/qsm-configuration-context.ts +31 -31
  385. package/src/qsm/store/qsm-slice.ts +275 -275
  386. package/src/qsm/types.ts +110 -110
  387. package/src/search-results/components/filters/filters.tsx +230 -230
  388. package/src/search-results/components/filters/flight-filters.tsx +671 -671
  389. package/src/search-results/components/flight/flight-banner.tsx +35 -35
  390. package/src/search-results/components/flight/flight-results.tsx +208 -208
  391. package/src/search-results/components/flight/flight-search-context/index.tsx +628 -628
  392. package/src/search-results/components/flight/flight-selection/independent-flight-option.tsx +147 -147
  393. package/src/search-results/components/flight/flight-selection/independent-flight-selection.tsx +172 -172
  394. package/src/search-results/components/flight/flight-selection/index.tsx +19 -19
  395. package/src/search-results/components/flight/flight-selection/paired-flight-option.tsx +255 -255
  396. package/src/search-results/components/flight/flight-selection/paired-flight-selection.tsx +38 -38
  397. package/src/search-results/components/group-tour/group-tour-card.tsx +105 -105
  398. package/src/search-results/components/group-tour/group-tour-results.tsx +62 -62
  399. package/src/search-results/components/hotel/hotel-accommodation-results.tsx +176 -176
  400. package/src/search-results/components/hotel/hotel-card.tsx +113 -113
  401. package/src/search-results/components/icon.tsx +680 -680
  402. package/src/search-results/components/item-picker/index.tsx +81 -81
  403. package/src/search-results/components/itinerary/index.tsx +310 -310
  404. package/src/search-results/components/round-trip/round-trip-results.tsx +199 -199
  405. package/src/search-results/components/search-results-container/flight-search-results.tsx +137 -137
  406. package/src/search-results/components/search-results-container/search-results-container.tsx +893 -893
  407. package/src/search-results/components/spinner/spinner.tsx +16 -16
  408. package/src/search-results/components/tab-views/index.tsx +53 -53
  409. package/src/search-results/features/flights/flight-search-results-self-contained.tsx +294 -294
  410. package/src/search-results/features/hotels/hotel-flight-search-results-self-contained.tsx +143 -143
  411. package/src/search-results/features/hotels/hotel-search-results-self-contained.tsx +220 -220
  412. package/src/search-results/features/roundtrips/roundtrip-search-results-self-contained.tsx +65 -65
  413. package/src/search-results/store/search-results-slice.ts +158 -158
  414. package/src/search-results/types.ts +181 -181
  415. package/src/search-results/utils/flight-utils.ts +93 -93
  416. package/src/search-results/utils/search-results-utils.ts +251 -251
  417. package/src/shared/components/flyin/accommodation-flyin.tsx +422 -422
  418. package/src/shared/components/flyin/flights-flyin.tsx +503 -503
  419. package/src/shared/components/flyin/flyin.tsx +82 -82
  420. package/src/shared/components/flyin/group-tour-flyin.tsx +293 -293
  421. package/src/shared/components/icon.tsx +826 -826
  422. package/src/shared/translations/ar-SA.json +382 -382
  423. package/src/shared/translations/da-DK.json +382 -382
  424. package/src/shared/translations/de-DE.json +382 -382
  425. package/src/shared/translations/en-GB.json +386 -386
  426. package/src/shared/translations/es-ES.json +382 -382
  427. package/src/shared/translations/fr-BE.json +386 -386
  428. package/src/shared/translations/fr-FR.json +382 -382
  429. package/src/shared/translations/is-IS.json +382 -382
  430. package/src/shared/translations/it-IT.json +382 -382
  431. package/src/shared/translations/ja-JP.json +382 -382
  432. package/src/shared/translations/nl-BE.json +386 -386
  433. package/src/shared/translations/nl-NL.json +382 -382
  434. package/src/shared/translations/no-NO.json +382 -382
  435. package/src/shared/translations/pl-PL.json +382 -382
  436. package/src/shared/translations/pt-PT.json +382 -382
  437. package/src/shared/translations/sv-SE.json +382 -382
  438. package/src/shared/types.ts +31 -31
  439. package/src/shared/utils/localization-util.ts +275 -275
  440. package/styles/booking-search-results-variables.scss +728 -728
  441. package/styles/booking-search-results.scss +53 -53
  442. package/styles/components/_booking.scss +872 -872
  443. package/styles/components/_content.scss +336 -336
  444. package/styles/components/_flyin.scss +727 -727
  445. package/styles/components/_footer.scss +141 -141
  446. package/styles/components/_form.scss +1634 -1634
  447. package/styles/components/_image-with-text.scss +206 -206
  448. package/styles/components/_login.scss +140 -140
  449. package/styles/components/_navbar.scss +765 -765
  450. package/styles/components/_pricing-summary.scss +163 -163
  451. package/styles/components/_search.scss +2009 -2009
  452. package/styles/components/_tree.scss +648 -648
  453. package/styles/content-blocks.scss +64 -64
@@ -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
- agentId: context?.agentId,
155
- payload: {
156
- catalogueIds: context!.tideConnection.catalogueIds ?? [],
157
- serviceType:
158
- context!.searchConfiguration.qsmType === PortalQsmType.Accommodation || context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight
159
- ? 3
160
- : context!.searchConfiguration.qsmType === PortalQsmType.Flight
161
- ? 7
162
- : context!.searchConfiguration.qsmType === PortalQsmType.RoundTrip
163
- ? 1
164
- : 0,
165
- searchType: 0,
166
- destination: {
167
- id: Number(destinationId),
168
- isCountry: destinationIsCountry,
169
- isRegion: destinationIsRegion,
170
- isOord: destinationIsOord,
171
- isLocation: destinationIsLocation
172
- } as BookingPackageDestination,
173
- rooms: getRequestRoomsFromEntry(rooms),
174
- fromDate: from,
175
- toDate: to,
176
- earliestFromOffset: 0,
177
- latestToOffset: 0,
178
- includeFlights: true,
179
- regimeCodes: entry.items.map((i) => i.regimeCode) || [],
180
- useExactDates: true,
181
- onlyCachedResults: false,
182
- includeAllAllotments: true,
183
- productCodes: hotel ? [hotel] : []
184
- }
185
- };
186
-
187
- return searchRequest;
188
- };
189
-
190
- const buildSearchFromQueryParams = (params: URLSearchParams): BookingPackageRequest<BookingPackageSearchRequest> | null => {
191
- let from = getDateFromParams(params, 'fromDate');
192
- let to = getDateFromParams(params, 'toDate');
193
- const rooms = getRoomsFromParams(params, 'rooms');
194
- let country = getNumberFromParams(params, 'country');
195
- let region = getNumberFromParams(params, 'region');
196
- let oord = getNumberFromParams(params, 'oord');
197
- let city = getNumberFromParams(params, 'location');
198
- let hotel = getNumberFromParams(params, 'hotel');
199
- let tagId = getNumberFromParams(params, 'tagId');
200
-
201
- if (!from || !to) {
202
- console.error('Missing fromDate or toDate in query params, using default values');
203
- return null;
204
- }
205
-
206
- if (typeof window !== 'undefined') {
207
- window.scrollTo(0, 0);
208
- }
209
-
210
- let destinationId: number | null = null;
211
- let destinationIsCountry = false;
212
- let destinationIsRegion = false;
213
- let destinationIsOord = false;
214
- let destinationIsLocation = false;
215
-
216
- if (country) {
217
- destinationId = country;
218
- destinationIsCountry = true;
219
- } else if (region) {
220
- destinationId = region;
221
- destinationIsRegion = true;
222
- } else if (oord) {
223
- destinationId = oord;
224
- destinationIsOord = true;
225
- } else if (city) {
226
- destinationId = city;
227
- destinationIsLocation = true;
228
- }
229
-
230
- var searchRequest = {
231
- officeId: 1,
232
- agentId: context?.agentId,
233
- payload: {
234
- catalogueIds: context!.tideConnection.catalogueIds ?? [],
235
- serviceType:
236
- context!.searchConfiguration.qsmType === PortalQsmType.Accommodation || context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight
237
- ? 3
238
- : context!.searchConfiguration.qsmType === PortalQsmType.Flight
239
- ? 7
240
- : context!.searchConfiguration.qsmType === PortalQsmType.RoundTrip
241
- ? 1
242
- : undefined,
243
- searchType: context!.searchConfiguration.qsmType === PortalQsmType.GroupTour ? 1 : 0,
244
- destination: {
245
- id: Number(destinationId),
246
- isCountry: destinationIsCountry,
247
- isRegion: destinationIsRegion,
248
- isOord: destinationIsOord,
249
- isLocation: destinationIsLocation
250
- } as BookingPackageDestination,
251
- rooms: getRequestRooms(rooms),
252
- fromDate: from,
253
- toDate: to,
254
- earliestFromOffset: 0,
255
- latestToOffset: 0,
256
- includeFlights: context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight ? true : false,
257
- // regimeCodes:
258
- // filters
259
- // .find((f) => f.property === 'regime')
260
- // ?.options?.filter((o) => o.isChecked)
261
- // .flatMap((o) => o.value.toString()) || [],
262
- // minPrice: filters.find((f) => f.property === 'price')?.selectedMin,
263
- // maxPrice: filters.find((f) => f.property === 'price')?.selectedMax,
264
- useExactDates: context?.searchConfiguration.qsmType === PortalQsmType.GroupTour ? false : true,
265
- onlyCachedResults: false,
266
- includeAllAllotments: true,
267
- productIds: hotel ? [hotel] : [],
268
- productTagIds: tagId ? [tagId] : []
269
- }
270
- };
271
-
272
- console.log('Built search request from query params', searchRequest);
273
-
274
- return searchRequest;
275
- };
276
-
277
- const getRequestRoomsFromEntry = (rooms: EntryRoom[] | null) => {
278
- if (!rooms) {
279
- // Fall back to 2 adults
280
- var room = { index: 0, pax: [] } as BookingPackageRequestRoom;
281
- range(0, 2).forEach(() => {
282
- room.pax.push({
283
- age: 30
284
- } as BookingPackagePax);
285
- });
286
- return [room];
287
- }
288
-
289
- const requestRooms = rooms?.map((x, i) => {
290
- var room = { index: i, pax: [] } as BookingPackageRequestRoom;
291
- x.travellers.forEach((p) => {
292
- room.pax.push({
293
- age: p.age,
294
- dateOfBirth: p.dateOfBirth
295
- } as BookingPackagePax);
296
- });
297
-
298
- return room;
299
- });
300
-
301
- return requestRooms;
302
- };
303
-
304
- const getRequestRooms = (rooms: Room[] | null) => {
305
- if (!rooms) {
306
- // Fall back to 2 adults
307
- var room = { index: 0, pax: [] } as BookingPackageRequestRoom;
308
- range(0, 2).forEach(() => {
309
- room.pax.push({
310
- age: 30
311
- } as BookingPackagePax);
312
- });
313
- return [room];
314
- }
315
-
316
- const requestRooms = rooms?.map((x, i) => {
317
- var room = { index: i, pax: [] } as BookingPackageRequestRoom;
318
- range(0, x.adults).forEach(() => {
319
- room.pax.push({
320
- age: 30
321
- } as BookingPackagePax);
322
- });
323
- x.childAges.forEach((x) => {
324
- room.pax.push({
325
- age: x
326
- } as BookingPackagePax);
327
- });
328
- return room;
329
- });
330
-
331
- return requestRooms;
332
- };
333
-
334
- const buildPackagingAccommodationRequestFromQueryParams = (params: URLSearchParams): PackagingAccommodationRequest | null => {
335
- let from = getDateFromParams(params, 'fromDate');
336
- let to = getDateFromParams(params, 'toDate');
337
- const rooms = getRoomsFromParams(params, 'rooms');
338
- let country = getNumberFromParams(params, 'country');
339
- let region = getNumberFromParams(params, 'region');
340
- let oord = getNumberFromParams(params, 'oord');
341
- let city = getNumberFromParams(params, 'location');
342
- let hotel = getNumberFromParams(params, 'hotel');
343
- let tagId = getNumberFromParams(params, 'tagId');
344
- let agentId = getNumberFromParams(params, 'agentId');
345
- let destinationAirport = getStringFromParams(params, 'destinationAirport');
346
-
347
- if (!from || !to) {
348
- console.error('Missing fromDate or toDate in query params, using default values');
349
- return null;
350
- }
351
-
352
- if (typeof window !== 'undefined') {
353
- window.scrollTo(0, 0);
354
- }
355
-
356
- let destinationId: number | null = null;
357
- let destinationIsCountry = false;
358
- let destinationIsRegion = false;
359
- let destinationIsOord = false;
360
- let destinationIsLocation = false;
361
- let destinationCode: string | null = null;
362
- let destinationIsAirport = false;
363
-
364
- if (country) {
365
- destinationId = country;
366
- destinationIsCountry = true;
367
- } else if (region) {
368
- destinationId = region;
369
- destinationIsRegion = true;
370
- } else if (oord) {
371
- destinationId = oord;
372
- destinationIsOord = true;
373
- } else if (city) {
374
- destinationId = city;
375
- destinationIsLocation = true;
376
- } else if (destinationAirport) {
377
- destinationCode = destinationAirport;
378
- destinationIsAirport = true;
379
- }
380
-
381
- var searchRequest = {
382
- officeId: 1,
383
- agentId: agentId ?? null,
384
- catalogueId: context!.searchConfiguration.defaultCatalogueId ?? 0,
385
- searchConfigurationId: context!.searchConfiguration.id,
386
- language: context!.languageCode ?? 'en-GB',
387
- servicesType: 3, // accommodation
388
- fromDate: from,
389
- toDate: to,
390
- destination: {
391
- id: Number(destinationId),
392
- isCountry: destinationIsCountry,
393
- isRegion: destinationIsRegion,
394
- isOord: destinationIsOord,
395
- isLocation: destinationIsLocation,
396
- isAirport: destinationIsAirport,
397
- code: destinationCode
398
- } as PackagingDestination,
399
- productCode: hotel ? hotel.toString() : '',
400
- rooms: getPackagingRequestRooms(rooms),
401
- tagIds: tagId ? [tagId] : []
402
- };
403
-
404
- console.log('Search request for packaging accommodation from query params', searchRequest);
405
-
406
- return searchRequest;
407
- };
408
-
409
- const getPackagingRequestRooms = (rooms: Room[] | null) => {
410
- if (!rooms) {
411
- // Fall back to 2 adults
412
- var room = { index: 0, travellers: [] } as PackagingRoom;
413
- range(0, 2).forEach(() => {
414
- room.travellers.push({
415
- age: 30
416
- } as PackagingTraveller);
417
- });
418
- return [room];
419
- }
420
-
421
- const requestRooms = rooms?.map((x, i) => {
422
- var room = { index: i, travellers: [] } as PackagingRoom;
423
- range(0, x.adults).forEach(() => {
424
- room.travellers.push({
425
- age: 30
426
- } as PackagingTraveller);
427
- });
428
- x.childAges.forEach((x) => {
429
- room.travellers.push({
430
- age: x
431
- } as PackagingTraveller);
432
- });
433
- return room;
434
- });
435
-
436
- return requestRooms;
437
- };
438
-
439
- useEffect(() => {
440
- if (typeof document !== 'undefined') {
441
- document.body.classList.toggle('has-overlay', filtersOpen);
442
- }
443
- }, [filtersOpen]);
444
-
445
- // seperate Search
446
- useEffect(() => {
447
- const runSearch = async () => {
448
- dispatch(setIsLoading(true));
449
- try {
450
- if (!context) {
451
- return;
452
- }
453
-
454
- const config: TideClientConfig = {
455
- host: context.tideConnection.host,
456
- apiKey: context.tideConnection.apiKey
457
- };
458
-
459
- const params = new URLSearchParams(location.search);
460
- let entryId = getStringFromParams(params, 'entryId');
461
- let entryLight: EntryLight | null = null;
462
- // 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
463
-
464
- let searchRequest: BookingPackageRequest<BookingPackageSearchRequest>;
465
-
466
- if (entryId) {
467
- entryLight = await getEntryLight(config, entryId);
468
- // populate itinerary store
469
- dispatch(setEntry({ entry: entryLight }));
470
- searchRequest = buildSearchFromEntry(entryLight);
471
- } else {
472
- const rq = buildSearchFromQueryParams(params);
473
- if (!rq) {
474
- throw new Error('Invalid search parameters');
475
- }
476
-
477
- searchRequest = rq;
478
- }
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
+ agentId: context?.agentId,
155
+ payload: {
156
+ catalogueIds: context!.tideConnection.catalogueIds ?? [],
157
+ serviceType:
158
+ context!.searchConfiguration.qsmType === PortalQsmType.Accommodation || context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight
159
+ ? 3
160
+ : context!.searchConfiguration.qsmType === PortalQsmType.Flight
161
+ ? 7
162
+ : context!.searchConfiguration.qsmType === PortalQsmType.RoundTrip
163
+ ? 1
164
+ : 0,
165
+ searchType: 0,
166
+ destination: {
167
+ id: Number(destinationId),
168
+ isCountry: destinationIsCountry,
169
+ isRegion: destinationIsRegion,
170
+ isOord: destinationIsOord,
171
+ isLocation: destinationIsLocation
172
+ } as BookingPackageDestination,
173
+ rooms: getRequestRoomsFromEntry(rooms),
174
+ fromDate: from,
175
+ toDate: to,
176
+ earliestFromOffset: 0,
177
+ latestToOffset: 0,
178
+ includeFlights: true,
179
+ regimeCodes: entry.items.map((i) => i.regimeCode) || [],
180
+ useExactDates: true,
181
+ onlyCachedResults: false,
182
+ includeAllAllotments: true,
183
+ productCodes: hotel ? [hotel] : []
184
+ }
185
+ };
186
+
187
+ return searchRequest;
188
+ };
189
+
190
+ const buildSearchFromQueryParams = (params: URLSearchParams): BookingPackageRequest<BookingPackageSearchRequest> | null => {
191
+ let from = getDateFromParams(params, 'fromDate');
192
+ let to = getDateFromParams(params, 'toDate');
193
+ const rooms = getRoomsFromParams(params, 'rooms');
194
+ let country = getNumberFromParams(params, 'country');
195
+ let region = getNumberFromParams(params, 'region');
196
+ let oord = getNumberFromParams(params, 'oord');
197
+ let city = getNumberFromParams(params, 'location');
198
+ let hotel = getNumberFromParams(params, 'hotel');
199
+ let tagId = getNumberFromParams(params, 'tagId');
200
+
201
+ if (!from || !to) {
202
+ console.error('Missing fromDate or toDate in query params, using default values');
203
+ return null;
204
+ }
205
+
206
+ if (typeof window !== 'undefined') {
207
+ window.scrollTo(0, 0);
208
+ }
209
+
210
+ let destinationId: number | null = null;
211
+ let destinationIsCountry = false;
212
+ let destinationIsRegion = false;
213
+ let destinationIsOord = false;
214
+ let destinationIsLocation = false;
215
+
216
+ if (country) {
217
+ destinationId = country;
218
+ destinationIsCountry = true;
219
+ } else if (region) {
220
+ destinationId = region;
221
+ destinationIsRegion = true;
222
+ } else if (oord) {
223
+ destinationId = oord;
224
+ destinationIsOord = true;
225
+ } else if (city) {
226
+ destinationId = city;
227
+ destinationIsLocation = true;
228
+ }
229
+
230
+ var searchRequest = {
231
+ officeId: 1,
232
+ agentId: context?.agentId,
233
+ payload: {
234
+ catalogueIds: context!.tideConnection.catalogueIds ?? [],
235
+ serviceType:
236
+ context!.searchConfiguration.qsmType === PortalQsmType.Accommodation || context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight
237
+ ? 3
238
+ : context!.searchConfiguration.qsmType === PortalQsmType.Flight
239
+ ? 7
240
+ : context!.searchConfiguration.qsmType === PortalQsmType.RoundTrip
241
+ ? 1
242
+ : undefined,
243
+ searchType: context!.searchConfiguration.qsmType === PortalQsmType.GroupTour ? 1 : 0,
244
+ destination: {
245
+ id: Number(destinationId),
246
+ isCountry: destinationIsCountry,
247
+ isRegion: destinationIsRegion,
248
+ isOord: destinationIsOord,
249
+ isLocation: destinationIsLocation
250
+ } as BookingPackageDestination,
251
+ rooms: getRequestRooms(rooms),
252
+ fromDate: from,
253
+ toDate: to,
254
+ earliestFromOffset: 0,
255
+ latestToOffset: 0,
256
+ includeFlights: context!.searchConfiguration.qsmType === PortalQsmType.AccommodationAndFlight ? true : false,
257
+ // regimeCodes:
258
+ // filters
259
+ // .find((f) => f.property === 'regime')
260
+ // ?.options?.filter((o) => o.isChecked)
261
+ // .flatMap((o) => o.value.toString()) || [],
262
+ // minPrice: filters.find((f) => f.property === 'price')?.selectedMin,
263
+ // maxPrice: filters.find((f) => f.property === 'price')?.selectedMax,
264
+ useExactDates: context?.searchConfiguration.qsmType === PortalQsmType.GroupTour ? false : true,
265
+ onlyCachedResults: false,
266
+ includeAllAllotments: true,
267
+ productIds: hotel ? [hotel] : [],
268
+ productTagIds: tagId ? [tagId] : []
269
+ }
270
+ };
271
+
272
+ console.log('Built search request from query params', searchRequest);
273
+
274
+ return searchRequest;
275
+ };
276
+
277
+ const getRequestRoomsFromEntry = (rooms: EntryRoom[] | null) => {
278
+ if (!rooms) {
279
+ // Fall back to 2 adults
280
+ var room = { index: 0, pax: [] } as BookingPackageRequestRoom;
281
+ range(0, 2).forEach(() => {
282
+ room.pax.push({
283
+ age: 30
284
+ } as BookingPackagePax);
285
+ });
286
+ return [room];
287
+ }
288
+
289
+ const requestRooms = rooms?.map((x, i) => {
290
+ var room = { index: i, pax: [] } as BookingPackageRequestRoom;
291
+ x.travellers.forEach((p) => {
292
+ room.pax.push({
293
+ age: p.age,
294
+ dateOfBirth: p.dateOfBirth
295
+ } as BookingPackagePax);
296
+ });
297
+
298
+ return room;
299
+ });
300
+
301
+ return requestRooms;
302
+ };
303
+
304
+ const getRequestRooms = (rooms: Room[] | null) => {
305
+ if (!rooms) {
306
+ // Fall back to 2 adults
307
+ var room = { index: 0, pax: [] } as BookingPackageRequestRoom;
308
+ range(0, 2).forEach(() => {
309
+ room.pax.push({
310
+ age: 30
311
+ } as BookingPackagePax);
312
+ });
313
+ return [room];
314
+ }
315
+
316
+ const requestRooms = rooms?.map((x, i) => {
317
+ var room = { index: i, pax: [] } as BookingPackageRequestRoom;
318
+ range(0, x.adults).forEach(() => {
319
+ room.pax.push({
320
+ age: 30
321
+ } as BookingPackagePax);
322
+ });
323
+ x.childAges.forEach((x) => {
324
+ room.pax.push({
325
+ age: x
326
+ } as BookingPackagePax);
327
+ });
328
+ return room;
329
+ });
330
+
331
+ return requestRooms;
332
+ };
333
+
334
+ const buildPackagingAccommodationRequestFromQueryParams = (params: URLSearchParams): PackagingAccommodationRequest | null => {
335
+ let from = getDateFromParams(params, 'fromDate');
336
+ let to = getDateFromParams(params, 'toDate');
337
+ const rooms = getRoomsFromParams(params, 'rooms');
338
+ let country = getNumberFromParams(params, 'country');
339
+ let region = getNumberFromParams(params, 'region');
340
+ let oord = getNumberFromParams(params, 'oord');
341
+ let city = getNumberFromParams(params, 'location');
342
+ let hotel = getNumberFromParams(params, 'hotel');
343
+ let tagId = getNumberFromParams(params, 'tagId');
344
+ let agentId = getNumberFromParams(params, 'agentId');
345
+ let destinationAirport = getStringFromParams(params, 'destinationAirport');
346
+
347
+ if (!from || !to) {
348
+ console.error('Missing fromDate or toDate in query params, using default values');
349
+ return null;
350
+ }
351
+
352
+ if (typeof window !== 'undefined') {
353
+ window.scrollTo(0, 0);
354
+ }
355
+
356
+ let destinationId: number | null = null;
357
+ let destinationIsCountry = false;
358
+ let destinationIsRegion = false;
359
+ let destinationIsOord = false;
360
+ let destinationIsLocation = false;
361
+ let destinationCode: string | null = null;
362
+ let destinationIsAirport = false;
363
+
364
+ if (country) {
365
+ destinationId = country;
366
+ destinationIsCountry = true;
367
+ } else if (region) {
368
+ destinationId = region;
369
+ destinationIsRegion = true;
370
+ } else if (oord) {
371
+ destinationId = oord;
372
+ destinationIsOord = true;
373
+ } else if (city) {
374
+ destinationId = city;
375
+ destinationIsLocation = true;
376
+ } else if (destinationAirport) {
377
+ destinationCode = destinationAirport;
378
+ destinationIsAirport = true;
379
+ }
380
+
381
+ var searchRequest = {
382
+ officeId: 1,
383
+ agentId: agentId ?? null,
384
+ catalogueId: context!.searchConfiguration.defaultCatalogueId ?? 0,
385
+ searchConfigurationId: context!.searchConfiguration.id,
386
+ language: context!.languageCode ?? 'en-GB',
387
+ servicesType: 3, // accommodation
388
+ fromDate: from,
389
+ toDate: to,
390
+ destination: {
391
+ id: Number(destinationId),
392
+ isCountry: destinationIsCountry,
393
+ isRegion: destinationIsRegion,
394
+ isOord: destinationIsOord,
395
+ isLocation: destinationIsLocation,
396
+ isAirport: destinationIsAirport,
397
+ code: destinationCode
398
+ } as PackagingDestination,
399
+ productCode: hotel ? hotel.toString() : '',
400
+ rooms: getPackagingRequestRooms(rooms),
401
+ tagIds: tagId ? [tagId] : []
402
+ };
403
+
404
+ console.log('Search request for packaging accommodation from query params', searchRequest);
405
+
406
+ return searchRequest;
407
+ };
408
+
409
+ const getPackagingRequestRooms = (rooms: Room[] | null) => {
410
+ if (!rooms) {
411
+ // Fall back to 2 adults
412
+ var room = { index: 0, travellers: [] } as PackagingRoom;
413
+ range(0, 2).forEach(() => {
414
+ room.travellers.push({
415
+ age: 30
416
+ } as PackagingTraveller);
417
+ });
418
+ return [room];
419
+ }
420
+
421
+ const requestRooms = rooms?.map((x, i) => {
422
+ var room = { index: i, travellers: [] } as PackagingRoom;
423
+ range(0, x.adults).forEach(() => {
424
+ room.travellers.push({
425
+ age: 30
426
+ } as PackagingTraveller);
427
+ });
428
+ x.childAges.forEach((x) => {
429
+ room.travellers.push({
430
+ age: x
431
+ } as PackagingTraveller);
432
+ });
433
+ return room;
434
+ });
435
+
436
+ return requestRooms;
437
+ };
438
+
439
+ useEffect(() => {
440
+ if (typeof document !== 'undefined') {
441
+ document.body.classList.toggle('has-overlay', filtersOpen);
442
+ }
443
+ }, [filtersOpen]);
444
+
445
+ // seperate Search
446
+ useEffect(() => {
447
+ const runSearch = async () => {
448
+ dispatch(setIsLoading(true));
449
+ try {
450
+ if (!context) {
451
+ return;
452
+ }
453
+
454
+ const config: TideClientConfig = {
455
+ host: context.tideConnection.host,
456
+ apiKey: context.tideConnection.apiKey
457
+ };
458
+
459
+ const params = new URLSearchParams(location.search);
460
+ let entryId = getStringFromParams(params, 'entryId');
461
+ let entryLight: EntryLight | null = null;
462
+ // 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
463
+
464
+ let searchRequest: BookingPackageRequest<BookingPackageSearchRequest>;
465
+
466
+ if (entryId) {
467
+ entryLight = await getEntryLight(config, entryId);
468
+ // populate itinerary store
469
+ dispatch(setEntry({ entry: entryLight }));
470
+ searchRequest = buildSearchFromEntry(entryLight);
471
+ } else {
472
+ const rq = buildSearchFromQueryParams(params);
473
+ if (!rq) {
474
+ throw new Error('Invalid search parameters');
475
+ }
476
+
477
+ searchRequest = rq;
478
+ }
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;