@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,1101 +1,1101 @@
1
- import { compact, get, sortBy } from 'lodash';
2
- import React, { useContext, useEffect, useState } from 'react';
3
- import { useSelector } from 'react-redux';
4
- import { fetchPackage, setCurrentStep, setHasMounted, setIsFetching } from '../booking/booking-slice';
5
- import {
6
- selectBookingAttributes,
7
- selectCountries,
8
- selectHasMounted,
9
- selectIsFetching,
10
- selectIsUnavailable,
11
- selectTravelersFirstStep
12
- } from '../booking/selectors';
13
- import { selectFormRooms, selectTravelersFormValues, setFormValues } from './travelers-form-slice';
14
-
15
- import { Link, useNavigate } from 'react-router-dom';
16
- import { format, parse } from 'date-fns';
17
- import flat from 'flat';
18
- import { useFormik } from 'formik';
19
- import produce from 'immer';
20
- import { buildClassName } from '../../../shared/utils/class-util';
21
- import LabeledInput from '../../components/labeled-input';
22
- import LabeledSelect from '../../components/labeled-select';
23
- import SettingsContext from '../../settings-context';
24
- import { useAppDispatch } from '../../store';
25
- import { RoomTraveler, Traveler, TravelersFormValues } from '../../types';
26
- import { setBookingType } from '../booking/booking-slice';
27
- import { FLIGHT_OPTIONS_FORM_STEP, OPTIONS_FORM_STEP, SUMMARY_STEP } from '../booking/constants';
28
- import { selectAgentAdressId, selectAgents, selectBookingQueryString, selectBookingType, selectStartDate, selectTranslations } from '../booking/selectors';
29
- import { fetchPriceDetails } from '../price-details/price-details-slice';
30
- import GenderControl from './controls/gender-control';
31
- import TypeAheadInput from './type-ahead-input';
32
- import validateForm from './validate-form';
33
- import PhoneInput from '../../components/phone-input';
34
-
35
- interface TravelersFormProps {}
36
-
37
- function createTraveler(traveler: RoomTraveler, followNumber: { number: number }, personTranslation?: string, isCompact?: boolean) {
38
- if (isCompact) {
39
- return {
40
- id: traveler.id,
41
- firstName: personTranslation,
42
- lastName: `${followNumber.number++}`,
43
- birthDate: '',
44
- gender: '',
45
- age: traveler.age || 30
46
- } as Traveler;
47
- } else {
48
- return {
49
- id: traveler.id,
50
- firstName: '',
51
- lastName: '',
52
- birthDate: '',
53
- gender: ''
54
- } as Traveler;
55
- }
56
- }
57
-
58
- function createInitialValues(
59
- formRooms: { adults: RoomTraveler[]; children: RoomTraveler[] }[],
60
- startDate?: string,
61
- agentAdressId?: number,
62
- personTranslation?: string,
63
- isCompact?: boolean
64
- ) {
65
- let followNumber = { number: 1 };
66
-
67
- const initialValues = {
68
- startDate: startDate,
69
- rooms: formRooms.map((r) => ({
70
- adults: r.adults.map((x) => createTraveler(x, followNumber, personTranslation, isCompact)),
71
- children: r.children.map((x) => createTraveler(x, followNumber, personTranslation, isCompact))
72
- })),
73
- mainBookerId: -1,
74
- street: '',
75
- houseNumber: '',
76
- box: '',
77
- zipCode: '',
78
- place: '',
79
- country: '',
80
- phone: '',
81
- email: '',
82
- emailConfirmation: '',
83
- travelAgentId: agentAdressId ?? 0,
84
- travelAgentName: ''
85
- };
86
-
87
- if (initialValues.rooms && initialValues.rooms.length && initialValues.rooms[0].adults && initialValues.rooms[0].adults.length) {
88
- initialValues.mainBookerId = initialValues.rooms[0].adults[0].id;
89
- }
90
-
91
- return initialValues;
92
- }
93
-
94
- const TravelersForm: React.FC<TravelersFormProps> = () => {
95
- const dispatch = useAppDispatch();
96
- const settings = useContext(SettingsContext);
97
- const navigate = settings.skipRouter ? () => {} : useNavigate();
98
- const bookingQueryString = useSelector(selectBookingQueryString);
99
- const startDate = useSelector(selectStartDate);
100
- const formRooms = useSelector(selectFormRooms);
101
- const bookingType = useSelector(selectBookingType);
102
- const agents = useSelector(selectAgents);
103
- const agentAdressId = useSelector(selectAgentAdressId);
104
- const translations = useSelector(selectTranslations);
105
- const travelersFirstStep = useSelector(selectTravelersFirstStep);
106
- const isUnavailable = useSelector(selectIsUnavailable);
107
- const bookingAttributes = useSelector(selectBookingAttributes);
108
- const isFetching = useSelector(selectIsFetching);
109
- const hasMounted = useSelector(selectHasMounted);
110
- const countries = useSelector(selectCountries);
111
-
112
- const useCompactForm = !!settings.travellers.compactForm && !!settings.agentAdressId;
113
- const showAllCountries = !!settings.travellers.showAllCountries;
114
-
115
- const initialValues =
116
- useSelector(selectTravelersFormValues) ?? createInitialValues(formRooms, startDate, agentAdressId, translations.TRAVELERS_FORM.PERSON, useCompactForm);
117
-
118
- const [showAgents, setShowAgents] = useState<boolean>(settings.agentRequired ?? false);
119
- const [showAgentSelection, setShowAgentSelection] = useState<boolean>(!settings.agentAdressId && !settings.hideAgentSelection);
120
-
121
- const typeaheadAgents =
122
- sortBy(
123
- agents?.map((x) => ({
124
- key: `${x.id}`,
125
- value: `${x.name} (${x.postalCode} ${x.location})`,
126
- text: `${x.name} (${x.postalCode} ${x.location})`
127
- })),
128
- 'value'
129
- ) ?? [];
130
-
131
- const [filteredAgents, setFilteredAgents] = useState<{ key: string; value: string; text: string }[]>(typeaheadAgents);
132
-
133
- const formik = useCompactForm
134
- ? useFormik<TravelersFormValues>({
135
- initialValues,
136
- validate: (values) => {},
137
- onSubmit: (values) => {
138
- dispatch(setFormValues(values));
139
- dispatch(fetchPriceDetails());
140
-
141
- if (settings.skipRouter) {
142
- dispatch(setCurrentStep(SUMMARY_STEP));
143
- } else {
144
- navigate(`${!settings.skipBasePathInRouting ? settings.basePath : ''}${settings.summary.pathSuffix}?${bookingQueryString}`);
145
- }
146
- }
147
- })
148
- : useFormik<TravelersFormValues>({
149
- initialValues,
150
- validate: (values) =>
151
- validateForm(values, settings.agentRequired, bookingType, translations, settings.travellers.formFields, settings.travellers.mainBookerFormFields),
152
- onSubmit: (values) => {
153
- dispatch(setFormValues(values));
154
- dispatch(fetchPackage());
155
-
156
- if (settings.skipRouter) {
157
- if (travelersFirstStep) {
158
- dispatch(setCurrentStep(FLIGHT_OPTIONS_FORM_STEP));
159
- } else {
160
- dispatch(setCurrentStep(SUMMARY_STEP));
161
- }
162
- } else {
163
- if (travelersFirstStep) {
164
- navigate(`${!settings.skipBasePathInRouting ? settings.basePath : ''}${settings.flightOptions.pathSuffix}?${bookingQueryString}`);
165
- } else {
166
- navigate(`${!settings.skipBasePathInRouting ? settings.basePath : ''}${settings.summary.pathSuffix}?${bookingQueryString}`);
167
- }
168
- }
169
- }
170
- });
171
-
172
- useEffect(() => {
173
- dispatch(fetchPriceDetails());
174
- }, []);
175
-
176
- useEffect(() => {
177
- if (!bookingAttributes?.rooms?.length || isFetching) return;
178
-
179
- if (!hasMounted) {
180
- dispatch(setHasMounted(true));
181
- return;
182
- }
183
-
184
- const fetchAll = async () => {
185
- dispatch(setIsFetching(true));
186
-
187
- try {
188
- await dispatch(fetchPackage());
189
- await dispatch(fetchPriceDetails());
190
- } finally {
191
- dispatch(setIsFetching(false));
192
- }
193
- };
194
-
195
- fetchAll();
196
- }, [bookingAttributes?.rooms]);
197
-
198
- // Update URL querystring when form data changes
199
- useEffect(() => {
200
- if (settings.skipRouter || !travelersFirstStep) return;
201
- const params = new URLSearchParams(bookingQueryString);
202
- params.delete('rooms');
203
- const roomsString = formik.values.rooms
204
- .map((room) => {
205
- const adults = room.adults ? room.adults.length : 0;
206
- const childAges = room.children && room.children.length ? room.children.map((c) => c.age).join(',') : '';
207
- return `adults:${adults},childAges:(${childAges})`;
208
- })
209
- .map((s) => `(${s})`)
210
- .join(',');
211
- let query = params.toString();
212
- if (query) {
213
- query += `&rooms=(${roomsString})`;
214
- } else {
215
- query = `rooms=(${roomsString})`;
216
- }
217
- const newUrl = `${window.location.pathname}?${query}`;
218
- navigate(newUrl, { replace: true });
219
- }, [formik.values]);
220
-
221
- useEffect(() => {
222
- if (agents && settings.affiliateSlug) {
223
- const agent = agents.find((x) => x.affiliateSlug && x.affiliateSlug === settings.affiliateSlug);
224
- if (!agent) return;
225
-
226
- const formValues = produce(formik.values, (values) => {
227
- (values.travelAgentId = Number(agent.id)), (values.travelAgentName = agent.name);
228
- });
229
- formik.setValues(formValues, false);
230
- dispatch(setFormValues(formValues));
231
- setShowAgentSelection(false);
232
- }
233
- }, [agents, settings.affiliateSlug]);
234
-
235
- const handleMainBookerChange: React.FormEventHandler<HTMLInputElement> = (e) => {
236
- const id = parseInt(e.currentTarget.value);
237
-
238
- formik.setFieldValue('mainBookerId', id);
239
- };
240
-
241
- const mainBooker = formik.values.rooms
242
- .find((r) => r.adults.find((traveler) => traveler.id === formik.values.mainBookerId))
243
- ?.adults.find((traveler) => traveler.id === formik.values.mainBookerId);
244
-
245
- const handleAgentChange = (value: string) => {
246
- const filteredAgents = typeaheadAgents.filter((x) => x.value.toLocaleLowerCase().indexOf(value.toLocaleLowerCase()) > -1);
247
-
248
- setFilteredAgents(filteredAgents);
249
- formik.setFieldValue('travelAgentName', value);
250
- };
251
-
252
- const handleAgentSelect = (key: string) => {
253
- const agent = typeaheadAgents.find((x) => x.key === key);
254
-
255
- formik.setValues({
256
- ...formik.values,
257
- travelAgentId: Number(agent?.key),
258
- travelAgentName: agent?.value ?? ''
259
- });
260
-
261
- let bookingType = 'b2b2c';
262
- if (agentAdressId && agentAdressId != 0) {
263
- bookingType = 'b2b';
264
- }
265
- dispatch(setBookingType(bookingType));
266
- };
267
-
268
- const handleAgentClear = () => {
269
- formik.setValues({
270
- ...formik.values,
271
- travelAgentId: 0,
272
- travelAgentName: ''
273
- });
274
-
275
- dispatch(setBookingType('b2c'));
276
- };
277
-
278
- const handleAddTraveler = (roomIndex: number) => {
279
- const rooms = [...formik.values.rooms];
280
- const newAdult = {
281
- id: Date.now(),
282
- firstName: '',
283
- lastName: '',
284
- birthDate: '',
285
- gender: ''
286
- };
287
- rooms[roomIndex] = {
288
- ...rooms[roomIndex],
289
- adults: [...rooms[roomIndex].adults, newAdult]
290
- };
291
- formik.setFieldValue('rooms', rooms);
292
- };
293
-
294
- const handleRemoveTraveler = (roomIndex: number, travelerIndex: number) => {
295
- const rooms = [...formik.values.rooms];
296
- const adults = [...rooms[roomIndex].adults];
297
- if (adults.length <= 1) {
298
- return;
299
- }
300
- adults.splice(travelerIndex, 1);
301
- rooms[roomIndex] = {
302
- ...rooms[roomIndex],
303
- adults
304
- };
305
- formik.setFieldValue('rooms', rooms);
306
- };
307
-
308
- const handleAddRoom = () => {
309
- const rooms = [...formik.values.rooms];
310
- const newAdult = {
311
- id: Date.now(),
312
- firstName: '',
313
- lastName: '',
314
- birthDate: '',
315
- gender: ''
316
- };
317
- rooms.push({ adults: [newAdult], children: [] });
318
- formik.setFieldValue('rooms', rooms);
319
- };
320
-
321
- const handleRemoveRoom = (roomIndex: number) => {
322
- const rooms = [...formik.values.rooms];
323
- rooms.splice(roomIndex, 1);
324
- formik.setFieldValue('rooms', rooms);
325
- };
326
-
327
- const toggleAgent = (value: boolean) => {
328
- setShowAgents(value);
329
-
330
- if (!value) {
331
- handleAgentClear();
332
- setFilteredAgents([]);
333
- }
334
- };
335
-
336
- const goPrevious = () => {
337
- dispatch(setCurrentStep(OPTIONS_FORM_STEP));
338
- };
339
-
340
- const flatErrors: Record<string, string> = flat(formik.errors);
341
- const errorKeys = Object.keys(flatErrors).filter((key) => get(formik.touched, key));
342
-
343
- const hasVisibleError = (key: string) => get(formik.errors, key) && get(formik.touched, key);
344
-
345
- const getControl = (type: string, value: Traveler, name: string) => {
346
- switch (type) {
347
- case 'gender': {
348
- return <GenderControl translations={translations} value={value} formik={formik} name={name} />;
349
- }
350
- case 'firstName': {
351
- return (
352
- <LabeledInput
353
- hasError={hasVisibleError(name)}
354
- extraClassName="form__group--md-33"
355
- label={translations.TRAVELERS_FORM.FIRST_NAME}
356
- required
357
- name={name}
358
- onChange={formik.handleChange}
359
- onBlur={formik.handleBlur}
360
- value={value.firstName}
361
- />
362
- );
363
- }
364
- case 'lastName': {
365
- return (
366
- <LabeledInput
367
- hasError={hasVisibleError(name)}
368
- extraClassName="form__group--md-33"
369
- label={translations.TRAVELERS_FORM.LAST_NAME}
370
- required
371
- name={name}
372
- onChange={formik.handleChange}
373
- onBlur={formik.handleBlur}
374
- value={value.lastName}
375
- />
376
- );
377
- }
378
- case 'birthDate': {
379
- return (
380
- <LabeledInput
381
- type="date"
382
- hasError={hasVisibleError(name)}
383
- extraClassName="form__group--md-33"
384
- label={translations.TRAVELERS_FORM.BIRTHDATE}
385
- required
386
- name={name}
387
- onChange={formik.handleChange}
388
- onBlur={formik.handleBlur}
389
- value={value.birthDate}
390
- />
391
- );
392
- }
393
- case 'country': {
394
- return (
395
- <LabeledSelect
396
- hasError={hasVisibleError('country')}
397
- label={translations.TRAVELERS_FORM.COUNTRY}
398
- required
399
- name="country"
400
- onChange={formik.handleChange}
401
- onBlur={formik.handleBlur}
402
- value={formik.values.country}
403
- options={[
404
- {
405
- key: 'empty',
406
- value: undefined,
407
- label: translations.TRAVELERS_FORM.SELECT_COUNTRY
408
- },
409
- ...(showAllCountries
410
- ? countries?.map((country) => ({
411
- key: country.iso2,
412
- value: country.iso2,
413
- label: country.name
414
- })) ?? []
415
- : settings.travellers?.countries?.map((country) => ({
416
- key: country.iso2,
417
- value: country.iso2,
418
- label: country.name
419
- })) ?? [])
420
- ]}
421
- />
422
- );
423
- }
424
- case 'phone': {
425
- return (
426
- <PhoneInput
427
- countries={settings.travellers?.countries ?? []}
428
- countryIso2={formik.values.country}
429
- hasError={hasVisibleError('phone')}
430
- label={translations.TRAVELERS_FORM.PHONE}
431
- required
432
- name="phone"
433
- onChange={formik.handleChange}
434
- onBlur={formik.handleBlur}
435
- value={formik.values.phone}
436
- />
437
- );
438
- }
439
- case 'email': {
440
- return (
441
- <>
442
- <LabeledInput
443
- type="email"
444
- hasError={hasVisibleError('email')}
445
- extraClassName="form__group--md-33"
446
- label={translations.TRAVELERS_FORM.EMAIL}
447
- required
448
- name="email"
449
- onChange={formik.handleChange}
450
- onBlur={formik.handleBlur}
451
- value={formik.values.email}
452
- />
453
- <LabeledInput
454
- type="email"
455
- hasError={hasVisibleError('emailConfirmation')}
456
- extraClassName="form__group--md-33"
457
- label={translations.TRAVELERS_FORM.REPEAT_EMAIL}
458
- required
459
- name="emailConfirmation"
460
- onChange={formik.handleChange}
461
- onBlur={formik.handleBlur}
462
- value={formik.values.emailConfirmation}
463
- />
464
- </>
465
- );
466
- }
467
- }
468
- };
469
-
470
- return (
471
- <form
472
- className="form form__travelers"
473
- name="booking--travellers"
474
- id="booking--travellers"
475
- noValidate
476
- onSubmit={formik.handleSubmit}
477
- onReset={formik.handleReset}>
478
- {useCompactForm ? (
479
- <div className="form__travelers__wrapper">
480
- {formik.values.rooms.map((room, rIndex) => (
481
- <div key={rIndex}>
482
- {formik.values.rooms.length > 1 && (
483
- <div className="form__region">
484
- <div className="form__region-header">
485
- <h5 className="form__region-heading">
486
- {translations.SHARED.ROOM} {rIndex + 1}
487
- </h5>
488
- <p className="form__region-label">
489
- {compact([
490
- room.adults.length,
491
- room.adults.length === 1 && ` ${translations.TRAVELERS_FORM.ADULT}`,
492
- room.adults.length > 1 && ` ${translations.TRAVELERS_FORM.ADULTS}`,
493
- room.adults && room.adults.length && room.children && room.children.length && ', ',
494
- room.children.length,
495
- room.children.length === 1 && ` ${translations.TRAVELERS_FORM.CHILD}`,
496
- room.children.length > 1 && ` ${translations.TRAVELERS_FORM.CHILDREN}`
497
- ]).join('')}
498
- </p>
499
- </div>
500
- </div>
501
- )}
502
- {room.adults.map((travelerValues, index) => (
503
- <div className="form__region" key={travelerValues.id}>
504
- <div className="form__region-header">
505
- <h5 className="form__region-heading">
506
- {translations.TRAVELERS_FORM.TRAVELER} {index + 1}
507
- </h5>
508
- <p className="form__region-label">{translations.TRAVELERS_FORM.ADULT}</p>
509
-
510
- <div className="radiobutton">
511
- <label className="radiobutton__label">
512
- <input
513
- type="radio"
514
- name="mainBookerId"
515
- onChange={handleMainBookerChange}
516
- onBlur={formik.handleBlur}
517
- value={travelerValues.id}
518
- checked={formik.values.mainBookerId === travelerValues.id}
519
- className="radiobutton__input"
520
- />
521
- {translations.TRAVELERS_FORM.MAIN_BOOKER}
522
- </label>
523
- </div>
524
- </div>
525
- <div className="form__row">
526
- <LabeledInput
527
- hasError={hasVisibleError(`rooms[${rIndex}].adults[${index}].age`)}
528
- extraClassName="form__group--md-33"
529
- label={translations.TRAVELERS_FORM.AGE}
530
- required
531
- name={`rooms[${rIndex}].adults[${index}].age`}
532
- onChange={formik.handleChange}
533
- onBlur={formik.handleBlur}
534
- value={travelerValues.age}
535
- />
536
- </div>
537
- </div>
538
- ))}
539
- {room.children.map((travelerValues, index) => (
540
- <div className="form__region" key={travelerValues.id}>
541
- <div className="form__region-header">
542
- <h5 className="form__region-heading">
543
- {translations.TRAVELERS_FORM.TRAVELER} {room.adults.length + index + 1}
544
- </h5>
545
- <p className="form__region-label">{translations.TRAVELERS_FORM.CHILD}</p>
546
- </div>
547
- <div className="form__row">
548
- <LabeledInput
549
- hasError={hasVisibleError(`rooms[${rIndex}].children[${index}].age`)}
550
- extraClassName="form__group--md-33"
551
- label={translations.TRAVELERS_FORM.AGE}
552
- required
553
- name={`rooms[${rIndex}].children[${index}].age`}
554
- onChange={formik.handleChange}
555
- onBlur={formik.handleBlur}
556
- value={travelerValues.age}
557
- />
558
- </div>
559
- </div>
560
- ))}
561
- </div>
562
- ))}
563
- </div>
564
- ) : (
565
- <>
566
- <div className="form__travelers__wrapper">
567
- {/* map each room */}
568
- {formik.values.rooms.map((room, rIndex) => (
569
- <div key={rIndex}>
570
- {formik.values.rooms.length > 1 && (
571
- <div className="form__region">
572
- <div className="form__region-header">
573
- <h5 className="form__region-heading">
574
- {translations.SHARED.ROOM} {rIndex + 1}
575
- </h5>
576
- <p className="form__region-label">
577
- {compact([
578
- room.adults.length,
579
- room.adults.length === 1 && ` ${translations.TRAVELERS_FORM.ADULT}`,
580
- room.adults.length > 1 && ` ${translations.TRAVELERS_FORM.ADULTS}`,
581
- room.adults && room.adults.length && room.children && room.children.length && ', ',
582
- room.children.length,
583
- room.children.length === 1 && ` ${translations.TRAVELERS_FORM.CHILD}`,
584
- room.children.length > 1 && ` ${translations.TRAVELERS_FORM.CHILDREN}`
585
- ]).join('')}
586
- </p>
587
- </div>
588
- {travelersFirstStep && formik.values.rooms.length > 1 && (
589
- <button type="button" className="cta cta--secondary" onClick={() => handleRemoveRoom(rIndex)}>
590
- Verwijder reisgezelschap
591
- </button>
592
- )}
593
- </div>
594
- )}
595
- {/* map adults here for the room */}
596
- {room.adults.map((travelerValues, index) => (
597
- <div className="form__region" key={travelerValues.id}>
598
- <div className="form__region-header">
599
- <h5 className="form__region-heading">
600
- {translations.TRAVELERS_FORM.TRAVELER} {index + 1}
601
- </h5>
602
- <p className="form__region-label">{translations.TRAVELERS_FORM.ADULT}</p>
603
-
604
- <div className="radiobutton">
605
- <label className="radiobutton__label">
606
- <input
607
- type="radio"
608
- name="mainBookerId"
609
- onChange={handleMainBookerChange}
610
- onBlur={formik.handleBlur}
611
- value={travelerValues.id}
612
- checked={formik.values.mainBookerId === travelerValues.id}
613
- className="radiobutton__input"
614
- />
615
- {translations.TRAVELERS_FORM.MAIN_BOOKER}
616
- </label>
617
- </div>
618
- </div>
619
- {settings.travellers.formFields?.length ? (
620
- <>
621
- <div className="travelers-form__grid">
622
- {settings.travellers.formFields.map((field, fIndex) => (
623
- <div key={fIndex} className={`control control--${field.type}`}>
624
- {getControl(field.type, travelerValues, `rooms[${rIndex}].adults[${index}].${field.type}`)}
625
- </div>
626
- ))}
627
- </div>
628
- </>
629
- ) : (
630
- <>
631
- <div className="form__row">
632
- <div className={buildClassName(['form__group', hasVisibleError(`rooms[${rIndex}].adults[${index}].gender`) && 'form__group--error'])}>
633
- <label className="form__label">{translations.TRAVELERS_FORM.GENDER_ID} *</label>
634
- <div className="radiobutton-group">
635
- <div className="radiobutton">
636
- <label className="radiobutton__label">
637
- <input
638
- type="radio"
639
- className="radiobutton__input"
640
- name={`rooms[${rIndex}].adults[${index}].gender`}
641
- onChange={formik.handleChange}
642
- onBlur={formik.handleBlur}
643
- value="m"
644
- checked={travelerValues.gender === 'm'}
645
- />
646
- {translations.TRAVELERS_FORM.MALE_GENDER}
647
- </label>
648
- </div>
649
-
650
- <div className="radiobutton">
651
- <label className="radiobutton__label">
652
- <input
653
- type="radio"
654
- className="radiobutton__input"
655
- name={`rooms[${rIndex}].adults[${index}].gender`}
656
- onChange={formik.handleChange}
657
- onBlur={formik.handleBlur}
658
- value="f"
659
- checked={travelerValues.gender === 'f'}
660
- />
661
- {translations.TRAVELERS_FORM.FEMALE_GENDER}
662
- </label>
663
- </div>
664
-
665
- {/* <div className="radiobutton">
666
- <label className="radiobutton__label">
667
- <input
668
- type="radio"
669
- className="radiobutton__input"
670
- name={`rooms[${rIndex}].adults[${index}].gender`}
671
- onChange={formik.handleChange}
672
- onBlur={formik.handleBlur}
673
- value="x"
674
- checked={travelerValues.gender === 'x'}
675
- />
676
- {translations.TRAVELERS_FORM.OTHER}
677
- </label>
678
- </div> */}
679
- </div>
680
- </div>
681
- </div>
682
- <div className="form__row">
683
- <LabeledInput
684
- hasError={hasVisibleError(`rooms[${rIndex}].adults[${index}].firstName`)}
685
- extraClassName="form__group--md-33"
686
- label={translations.TRAVELERS_FORM.FIRST_NAME}
687
- required
688
- name={`rooms[${rIndex}].adults[${index}].firstName`}
689
- onChange={formik.handleChange}
690
- onBlur={formik.handleBlur}
691
- value={travelerValues.firstName}
692
- />
693
- <LabeledInput
694
- hasError={hasVisibleError(`rooms[${rIndex}].adults[${index}].lastName`)}
695
- extraClassName="form__group--md-33"
696
- label={translations.TRAVELERS_FORM.LAST_NAME}
697
- required
698
- name={`rooms[${rIndex}].adults[${index}].lastName`}
699
- onChange={formik.handleChange}
700
- onBlur={formik.handleBlur}
701
- value={travelerValues.lastName}
702
- />
703
- <LabeledInput
704
- type="date"
705
- hasError={hasVisibleError(`rooms[${rIndex}].adults[${index}].birthDate`)}
706
- extraClassName="form__group--md-33"
707
- label={translations.TRAVELERS_FORM.BIRTHDATE}
708
- required
709
- name={`rooms[${rIndex}].adults[${index}].birthDate`}
710
- onChange={formik.handleChange}
711
- onBlur={formik.handleBlur}
712
- value={travelerValues.birthDate}
713
- />
714
- </div>
715
- {travelersFirstStep && room.adults.length > 1 && (
716
- <button type="button" className="cta cta--secondary" onClick={() => handleRemoveTraveler(rIndex, index)}>
717
- {translations.TRAVELERS_FORM.REMOVE_TRAVELER}
718
- </button>
719
- )}
720
- </>
721
- )}
722
- </div>
723
- ))}
724
- {room.children.map((travelerValues, index) => (
725
- <div className="form__region" key={travelerValues.id}>
726
- <div className="form__region-header">
727
- <h5 className="form__region-heading">
728
- {translations.TRAVELERS_FORM.TRAVELER} {room.adults.length + index + 1}
729
- </h5>
730
- <p className="form__region-label">{translations.TRAVELERS_FORM.CHILD}</p>
731
- </div>
732
- {settings.travellers.formFields?.length ? (
733
- <>
734
- <div className="travelers-form__grid">
735
- {settings.travellers.formFields.map((field, fIndex) => (
736
- <div key={fIndex} className={`control control--${field.type}`}>
737
- {getControl(field.type, travelerValues, `rooms[${rIndex}].children[${index}].${field.type}`)}
738
- </div>
739
- ))}
740
- </div>
741
- </>
742
- ) : (
743
- <>
744
- <div className="form__row">
745
- <div
746
- className={buildClassName(['form__group', hasVisibleError(`rooms[${rIndex}].children[${index}].gender`) && 'form__group--error'])}>
747
- <label className="form__label">{translations.TRAVELERS_FORM.GENDER_ID} *</label>
748
- <div className="radiobutton-group">
749
- <div className="radiobutton">
750
- <label className="radiobutton__label">
751
- <input
752
- type="radio"
753
- className="radiobutton__input"
754
- name={`rooms[${rIndex}].children[${index}].gender`}
755
- onChange={formik.handleChange}
756
- onBlur={formik.handleBlur}
757
- value="m"
758
- checked={travelerValues.gender === 'm'}
759
- />
760
- {translations.TRAVELERS_FORM.MALE_GENDER}
761
- </label>
762
- </div>
763
-
764
- <div className="radiobutton">
765
- <label className="radiobutton__label">
766
- <input
767
- type="radio"
768
- className="radiobutton__input"
769
- name={`rooms[${rIndex}].children[${index}].gender`}
770
- onChange={formik.handleChange}
771
- onBlur={formik.handleBlur}
772
- value="f"
773
- checked={travelerValues.gender === 'f'}
774
- />
775
- {translations.TRAVELERS_FORM.FEMALE_GENDER}
776
- </label>
777
- </div>
778
-
779
- {/* <div className="radiobutton">
780
- <label className="radiobutton__label">
781
- <input
782
- type="radio"
783
- className="radiobutton__input"
784
- name={`rooms[${rIndex}].children[${index}].gender`}
785
- onChange={formik.handleChange}
786
- onBlur={formik.handleBlur}
787
- value="x"
788
- checked={travelerValues.gender === 'x'}
789
- />
790
- {translations.TRAVELERS_FORM.OTHER}
791
- </label>
792
- </div> */}
793
- </div>
794
- </div>
795
- </div>
796
- <div className="form__row">
797
- <LabeledInput
798
- hasError={hasVisibleError(`rooms[${rIndex}].children[${index}].firstName`)}
799
- extraClassName="form__group--md-33"
800
- label={translations.TRAVELERS_FORM.FIRST_NAME}
801
- required
802
- name={`rooms[${rIndex}].children[${index}].firstName`}
803
- onChange={formik.handleChange}
804
- onBlur={formik.handleBlur}
805
- value={travelerValues.firstName}
806
- />
807
- <LabeledInput
808
- hasError={hasVisibleError(`rooms[${rIndex}].children[${index}].lastName`)}
809
- extraClassName="form__group--md-33"
810
- label={translations.TRAVELERS_FORM.LAST_NAME}
811
- required
812
- name={`rooms[${rIndex}].children[${index}].lastName`}
813
- onChange={formik.handleChange}
814
- onBlur={formik.handleBlur}
815
- value={travelerValues.lastName}
816
- />
817
- <LabeledInput
818
- type="date"
819
- hasError={hasVisibleError(`rooms[${rIndex}].children[${index}].birthDate`)}
820
- extraClassName="form__group--md-33"
821
- label={translations.TRAVELERS_FORM.BIRTHDATE}
822
- required
823
- name={`rooms[${rIndex}].children[${index}].birthDate`}
824
- onChange={formik.handleChange}
825
- onBlur={formik.handleBlur}
826
- value={travelerValues.birthDate}
827
- />
828
- </div>
829
- </>
830
- )}
831
- </div>
832
- ))}
833
- {travelersFirstStep && (
834
- <div className="form__region">
835
- <button type="button" className="cta cta--select" onClick={() => handleAddTraveler(rIndex)}>
836
- {translations.TRAVELERS_FORM.ADD_TRAVELER}
837
- </button>
838
- </div>
839
- )}
840
- </div>
841
- ))}
842
-
843
- {bookingType != 'b2b' || settings.travellers?.mainBookerFormFields?.length ? (
844
- <div className="form__region">
845
- <div className="form__region-header">
846
- <h5 className="form__region-heading">{translations.TRAVELERS_FORM.MAIN_BOOKER}</h5>
847
- <p className="form__region-label">
848
- {compact([
849
- compact([mainBooker?.firstName, mainBooker?.lastName]).join(' '),
850
- mainBooker?.birthDate && format(parse(mainBooker.birthDate, 'yyyy-MM-dd', new Date()), 'dd-MM-yyyy')
851
- ]).join(', ')}
852
- </p>
853
- </div>
854
- <>
855
- {settings.travellers?.mainBookerFormFields?.length ? (
856
- <>
857
- <div className="main-booker-form__grid">
858
- {settings.travellers.mainBookerFormFields.map((field, fIndex) => (
859
- <div key={fIndex} className={`control control--${field.type}`}>
860
- {getControl(field.type, {} as Traveler, field.type)}
861
- </div>
862
- ))}
863
- </div>
864
- </>
865
- ) : (
866
- <>
867
- <div className="form__twocolumn">
868
- <div className="form__twocolumn-column">
869
- <div className="form__row">
870
- <LabeledInput
871
- hasError={hasVisibleError('street')}
872
- extraClassName="form__group--50 form__group--sm-60"
873
- label={translations.TRAVELERS_FORM.STREET}
874
- required
875
- name="street"
876
- onChange={formik.handleChange}
877
- onBlur={formik.handleBlur}
878
- value={formik.values.street}
879
- />
880
- <LabeledInput
881
- hasError={hasVisibleError('houseNumber')}
882
- extraClassName="form__group--30 form__group--sm-20"
883
- label={translations.TRAVELERS_FORM.HOUSE_NUMBER}
884
- required
885
- name="houseNumber"
886
- onChange={formik.handleChange}
887
- onBlur={formik.handleBlur}
888
- value={formik.values.houseNumber}
889
- />
890
- <LabeledInput
891
- hasError={hasVisibleError('box')}
892
- extraClassName="form__group--20"
893
- label={translations.TRAVELERS_FORM.POST_BOX}
894
- name="box"
895
- onChange={formik.handleChange}
896
- onBlur={formik.handleBlur}
897
- value={formik.values.box}
898
- />
899
- </div>
900
- </div>
901
- <div className="form__twocolumn-column">
902
- <div className="form__row">
903
- <LabeledInput
904
- hasError={hasVisibleError('zipCode')}
905
- extraClassName="form__group--40 form__group--sm-20"
906
- label={translations.TRAVELERS_FORM.ZIPCODE}
907
- required
908
- name="zipCode"
909
- onChange={formik.handleChange}
910
- onBlur={formik.handleBlur}
911
- value={formik.values.zipCode}
912
- />
913
- <LabeledInput
914
- hasError={hasVisibleError('place')}
915
- extraClassName="form__group--60 form__group--sm-40"
916
- label={translations.TRAVELERS_FORM.CITY}
917
- required
918
- name="place"
919
- onChange={formik.handleChange}
920
- onBlur={formik.handleBlur}
921
- value={formik.values.place}
922
- />
923
- <LabeledSelect
924
- hasError={hasVisibleError('country')}
925
- extraClassName="form__group--sm-40"
926
- label={translations.TRAVELERS_FORM.COUNTRY}
927
- required
928
- name="country"
929
- onChange={formik.handleChange}
930
- onBlur={formik.handleBlur}
931
- value={formik.values.country}
932
- options={[
933
- {
934
- key: 'empty',
935
- value: undefined,
936
- label: translations.TRAVELERS_FORM.SELECT_COUNTRY
937
- },
938
- ...(showAllCountries
939
- ? countries?.map((country) => ({
940
- key: country.iso2,
941
- value: country.iso2,
942
- label: country.name
943
- })) ?? []
944
- : [
945
- {
946
- key: 'be',
947
- value: 'be',
948
- label: translations.TRAVELERS_FORM.COUNTRIES.BELGIUM
949
- },
950
- {
951
- key: 'nl',
952
- value: 'nl',
953
- label: translations.TRAVELERS_FORM.COUNTRIES.NETHERLANDS
954
- },
955
- {
956
- key: 'fr',
957
- value: 'fr',
958
- label: translations.TRAVELERS_FORM.COUNTRIES.FRANCE
959
- }
960
- ])
961
- ]}
962
- />
963
- </div>
964
- </div>
965
- </div>
966
- <div className="form__row">
967
- <LabeledInput
968
- hasError={hasVisibleError('phone')}
969
- extraClassName="form__group--md-33"
970
- label={translations.TRAVELERS_FORM.PHONE}
971
- required
972
- name="phone"
973
- onChange={formik.handleChange}
974
- onBlur={formik.handleBlur}
975
- value={formik.values.phone}
976
- />
977
- <LabeledInput
978
- type="email"
979
- hasError={hasVisibleError('email')}
980
- extraClassName="form__group--md-33"
981
- label={translations.TRAVELERS_FORM.EMAIL}
982
- required
983
- name="email"
984
- onChange={formik.handleChange}
985
- onBlur={formik.handleBlur}
986
- value={formik.values.email}
987
- />
988
- <LabeledInput
989
- type="email"
990
- hasError={hasVisibleError('emailConfirmation')}
991
- extraClassName="form__group--md-33"
992
- label={translations.TRAVELERS_FORM.REPEAT_EMAIL}
993
- required
994
- name="emailConfirmation"
995
- onChange={formik.handleChange}
996
- onBlur={formik.handleBlur}
997
- value={formik.values.emailConfirmation}
998
- />
999
- </div>
1000
- </>
1001
- )}
1002
- </>
1003
- </div>
1004
- ) : (
1005
- <div className="form__region">
1006
- <div className="form__row">
1007
- <LabeledInput
1008
- hasError={hasVisibleError('phone')}
1009
- extraClassName="form__group--md-33"
1010
- label={translations.TRAVELERS_FORM.PHONE}
1011
- required
1012
- name="phone"
1013
- onChange={formik.handleChange}
1014
- onBlur={formik.handleBlur}
1015
- value={formik.values.phone}
1016
- />
1017
- </div>
1018
- </div>
1019
- )}
1020
-
1021
- {showAgentSelection && (
1022
- <div className="form__region">
1023
- <div className="form__region-header">
1024
- <h5 className="form__region-heading">{translations.TRAVELERS_FORM.BOOK_WITH_AGENT}</h5>
1025
- <div className="checkbox" id="cbxChooseOffice">
1026
- <label className="checkbox__label">
1027
- <input
1028
- type="checkbox"
1029
- name="booking--mainbooker"
1030
- defaultChecked={showAgents}
1031
- onClick={() => toggleAgent(!showAgents)}
1032
- className="checkbox__input"
1033
- />
1034
- {translations.TRAVELERS_FORM.CHOOSE_OFFICE}
1035
- </label>
1036
- </div>
1037
- </div>
1038
- {showAgents && (
1039
- <div className="form__row form__row--choose-office">
1040
- <div className={buildClassName(['form__group', 'form__group--icon', hasVisibleError('travelAgentId') && 'form__group--error'])}>
1041
- <TypeAheadInput
1042
- value={formik.values.travelAgentName}
1043
- options={filteredAgents}
1044
- onChange={handleAgentChange}
1045
- onSelect={handleAgentSelect}
1046
- onClear={handleAgentClear}
1047
- name="travelAgentName"
1048
- placeholder={translations.TRAVELERS_FORM.CHOOSE_AGENT_PLACEHOLDER}
1049
- />
1050
- </div>
1051
- </div>
1052
- )}
1053
- </div>
1054
- )}
1055
- </div>
1056
- {errorKeys.length > 0 && (
1057
- <div className="form__region form__region--errors">
1058
- <div className="form__row">
1059
- <div className="form__group">
1060
- <p className="form__error-heading">{translations.TRAVELERS_FORM.VALIDATION_MESSAGE}:</p>
1061
- <ul className="list">
1062
- {errorKeys.map((key) => (
1063
- <li key={key}>{get(flatErrors, key)}</li>
1064
- ))}
1065
- </ul>
1066
- </div>
1067
- </div>
1068
- </div>
1069
- )}
1070
- </>
1071
- )}
1072
- {travelersFirstStep && (
1073
- <div className="booking__navigator">
1074
- <button type="button" className="cta cta--select" onClick={handleAddRoom}>
1075
- {translations.TRAVELERS_FORM.ADD_ROOM}
1076
- </button>
1077
- </div>
1078
- )}
1079
-
1080
- <div className="booking__navigator">
1081
- {!travelersFirstStep && settings.skipRouter ? (
1082
- <button type="button" title={translations.STEPS.PREVIOUS} onClick={() => goPrevious()} className="cta cta--secondary">
1083
- {translations.STEPS.PREVIOUS}
1084
- </button>
1085
- ) : !travelersFirstStep ? (
1086
- <Link
1087
- to={`${!settings.skipBasePathInRouting ? settings.basePath : ''}${settings.options.pathSuffix}?${bookingQueryString}`}
1088
- title={translations.STEPS.PREVIOUS}
1089
- className="cta cta--secondary">
1090
- {translations.STEPS.PREVIOUS}
1091
- </Link>
1092
- ) : null}
1093
- <button type="submit" title={translations.STEPS.NEXT} className={'cta' + (isUnavailable ? ' cta--disabled' : '')}>
1094
- {translations.STEPS.NEXT}
1095
- </button>
1096
- </div>
1097
- </form>
1098
- );
1099
- };
1100
-
1101
- export default TravelersForm;
1
+ import { compact, get, sortBy } from 'lodash';
2
+ import React, { useContext, useEffect, useState } from 'react';
3
+ import { useSelector } from 'react-redux';
4
+ import { fetchPackage, setCurrentStep, setHasMounted, setIsFetching } from '../booking/booking-slice';
5
+ import {
6
+ selectBookingAttributes,
7
+ selectCountries,
8
+ selectHasMounted,
9
+ selectIsFetching,
10
+ selectIsUnavailable,
11
+ selectTravelersFirstStep
12
+ } from '../booking/selectors';
13
+ import { selectFormRooms, selectTravelersFormValues, setFormValues } from './travelers-form-slice';
14
+
15
+ import { Link, useNavigate } from 'react-router-dom';
16
+ import { format, parse } from 'date-fns';
17
+ import flat from 'flat';
18
+ import { useFormik } from 'formik';
19
+ import produce from 'immer';
20
+ import { buildClassName } from '../../../shared/utils/class-util';
21
+ import LabeledInput from '../../components/labeled-input';
22
+ import LabeledSelect from '../../components/labeled-select';
23
+ import SettingsContext from '../../settings-context';
24
+ import { useAppDispatch } from '../../store';
25
+ import { RoomTraveler, Traveler, TravelersFormValues } from '../../types';
26
+ import { setBookingType } from '../booking/booking-slice';
27
+ import { FLIGHT_OPTIONS_FORM_STEP, OPTIONS_FORM_STEP, SUMMARY_STEP } from '../booking/constants';
28
+ import { selectAgentAdressId, selectAgents, selectBookingQueryString, selectBookingType, selectStartDate, selectTranslations } from '../booking/selectors';
29
+ import { fetchPriceDetails } from '../price-details/price-details-slice';
30
+ import GenderControl from './controls/gender-control';
31
+ import TypeAheadInput from './type-ahead-input';
32
+ import validateForm from './validate-form';
33
+ import PhoneInput from '../../components/phone-input';
34
+
35
+ interface TravelersFormProps {}
36
+
37
+ function createTraveler(traveler: RoomTraveler, followNumber: { number: number }, personTranslation?: string, isCompact?: boolean) {
38
+ if (isCompact) {
39
+ return {
40
+ id: traveler.id,
41
+ firstName: personTranslation,
42
+ lastName: `${followNumber.number++}`,
43
+ birthDate: '',
44
+ gender: '',
45
+ age: traveler.age || 30
46
+ } as Traveler;
47
+ } else {
48
+ return {
49
+ id: traveler.id,
50
+ firstName: '',
51
+ lastName: '',
52
+ birthDate: '',
53
+ gender: ''
54
+ } as Traveler;
55
+ }
56
+ }
57
+
58
+ function createInitialValues(
59
+ formRooms: { adults: RoomTraveler[]; children: RoomTraveler[] }[],
60
+ startDate?: string,
61
+ agentAdressId?: number,
62
+ personTranslation?: string,
63
+ isCompact?: boolean
64
+ ) {
65
+ let followNumber = { number: 1 };
66
+
67
+ const initialValues = {
68
+ startDate: startDate,
69
+ rooms: formRooms.map((r) => ({
70
+ adults: r.adults.map((x) => createTraveler(x, followNumber, personTranslation, isCompact)),
71
+ children: r.children.map((x) => createTraveler(x, followNumber, personTranslation, isCompact))
72
+ })),
73
+ mainBookerId: -1,
74
+ street: '',
75
+ houseNumber: '',
76
+ box: '',
77
+ zipCode: '',
78
+ place: '',
79
+ country: '',
80
+ phone: '',
81
+ email: '',
82
+ emailConfirmation: '',
83
+ travelAgentId: agentAdressId ?? 0,
84
+ travelAgentName: ''
85
+ };
86
+
87
+ if (initialValues.rooms && initialValues.rooms.length && initialValues.rooms[0].adults && initialValues.rooms[0].adults.length) {
88
+ initialValues.mainBookerId = initialValues.rooms[0].adults[0].id;
89
+ }
90
+
91
+ return initialValues;
92
+ }
93
+
94
+ const TravelersForm: React.FC<TravelersFormProps> = () => {
95
+ const dispatch = useAppDispatch();
96
+ const settings = useContext(SettingsContext);
97
+ const navigate = settings.skipRouter ? () => {} : useNavigate();
98
+ const bookingQueryString = useSelector(selectBookingQueryString);
99
+ const startDate = useSelector(selectStartDate);
100
+ const formRooms = useSelector(selectFormRooms);
101
+ const bookingType = useSelector(selectBookingType);
102
+ const agents = useSelector(selectAgents);
103
+ const agentAdressId = useSelector(selectAgentAdressId);
104
+ const translations = useSelector(selectTranslations);
105
+ const travelersFirstStep = useSelector(selectTravelersFirstStep);
106
+ const isUnavailable = useSelector(selectIsUnavailable);
107
+ const bookingAttributes = useSelector(selectBookingAttributes);
108
+ const isFetching = useSelector(selectIsFetching);
109
+ const hasMounted = useSelector(selectHasMounted);
110
+ const countries = useSelector(selectCountries);
111
+
112
+ const useCompactForm = !!settings.travellers.compactForm && !!settings.agentAdressId;
113
+ const showAllCountries = !!settings.travellers.showAllCountries;
114
+
115
+ const initialValues =
116
+ useSelector(selectTravelersFormValues) ?? createInitialValues(formRooms, startDate, agentAdressId, translations.TRAVELERS_FORM.PERSON, useCompactForm);
117
+
118
+ const [showAgents, setShowAgents] = useState<boolean>(settings.agentRequired ?? false);
119
+ const [showAgentSelection, setShowAgentSelection] = useState<boolean>(!settings.agentAdressId && !settings.hideAgentSelection);
120
+
121
+ const typeaheadAgents =
122
+ sortBy(
123
+ agents?.map((x) => ({
124
+ key: `${x.id}`,
125
+ value: `${x.name} (${x.postalCode} ${x.location})`,
126
+ text: `${x.name} (${x.postalCode} ${x.location})`
127
+ })),
128
+ 'value'
129
+ ) ?? [];
130
+
131
+ const [filteredAgents, setFilteredAgents] = useState<{ key: string; value: string; text: string }[]>(typeaheadAgents);
132
+
133
+ const formik = useCompactForm
134
+ ? useFormik<TravelersFormValues>({
135
+ initialValues,
136
+ validate: (values) => {},
137
+ onSubmit: (values) => {
138
+ dispatch(setFormValues(values));
139
+ dispatch(fetchPriceDetails());
140
+
141
+ if (settings.skipRouter) {
142
+ dispatch(setCurrentStep(SUMMARY_STEP));
143
+ } else {
144
+ navigate(`${!settings.skipBasePathInRouting ? settings.basePath : ''}${settings.summary.pathSuffix}?${bookingQueryString}`);
145
+ }
146
+ }
147
+ })
148
+ : useFormik<TravelersFormValues>({
149
+ initialValues,
150
+ validate: (values) =>
151
+ validateForm(values, settings.agentRequired, bookingType, translations, settings.travellers.formFields, settings.travellers.mainBookerFormFields),
152
+ onSubmit: (values) => {
153
+ dispatch(setFormValues(values));
154
+ dispatch(fetchPackage());
155
+
156
+ if (settings.skipRouter) {
157
+ if (travelersFirstStep) {
158
+ dispatch(setCurrentStep(FLIGHT_OPTIONS_FORM_STEP));
159
+ } else {
160
+ dispatch(setCurrentStep(SUMMARY_STEP));
161
+ }
162
+ } else {
163
+ if (travelersFirstStep) {
164
+ navigate(`${!settings.skipBasePathInRouting ? settings.basePath : ''}${settings.flightOptions.pathSuffix}?${bookingQueryString}`);
165
+ } else {
166
+ navigate(`${!settings.skipBasePathInRouting ? settings.basePath : ''}${settings.summary.pathSuffix}?${bookingQueryString}`);
167
+ }
168
+ }
169
+ }
170
+ });
171
+
172
+ useEffect(() => {
173
+ dispatch(fetchPriceDetails());
174
+ }, []);
175
+
176
+ useEffect(() => {
177
+ if (!bookingAttributes?.rooms?.length || isFetching) return;
178
+
179
+ if (!hasMounted) {
180
+ dispatch(setHasMounted(true));
181
+ return;
182
+ }
183
+
184
+ const fetchAll = async () => {
185
+ dispatch(setIsFetching(true));
186
+
187
+ try {
188
+ await dispatch(fetchPackage());
189
+ await dispatch(fetchPriceDetails());
190
+ } finally {
191
+ dispatch(setIsFetching(false));
192
+ }
193
+ };
194
+
195
+ fetchAll();
196
+ }, [bookingAttributes?.rooms]);
197
+
198
+ // Update URL querystring when form data changes
199
+ useEffect(() => {
200
+ if (settings.skipRouter || !travelersFirstStep) return;
201
+ const params = new URLSearchParams(bookingQueryString);
202
+ params.delete('rooms');
203
+ const roomsString = formik.values.rooms
204
+ .map((room) => {
205
+ const adults = room.adults ? room.adults.length : 0;
206
+ const childAges = room.children && room.children.length ? room.children.map((c) => c.age).join(',') : '';
207
+ return `adults:${adults},childAges:(${childAges})`;
208
+ })
209
+ .map((s) => `(${s})`)
210
+ .join(',');
211
+ let query = params.toString();
212
+ if (query) {
213
+ query += `&rooms=(${roomsString})`;
214
+ } else {
215
+ query = `rooms=(${roomsString})`;
216
+ }
217
+ const newUrl = `${window.location.pathname}?${query}`;
218
+ navigate(newUrl, { replace: true });
219
+ }, [formik.values]);
220
+
221
+ useEffect(() => {
222
+ if (agents && settings.affiliateSlug) {
223
+ const agent = agents.find((x) => x.affiliateSlug && x.affiliateSlug === settings.affiliateSlug);
224
+ if (!agent) return;
225
+
226
+ const formValues = produce(formik.values, (values) => {
227
+ (values.travelAgentId = Number(agent.id)), (values.travelAgentName = agent.name);
228
+ });
229
+ formik.setValues(formValues, false);
230
+ dispatch(setFormValues(formValues));
231
+ setShowAgentSelection(false);
232
+ }
233
+ }, [agents, settings.affiliateSlug]);
234
+
235
+ const handleMainBookerChange: React.FormEventHandler<HTMLInputElement> = (e) => {
236
+ const id = parseInt(e.currentTarget.value);
237
+
238
+ formik.setFieldValue('mainBookerId', id);
239
+ };
240
+
241
+ const mainBooker = formik.values.rooms
242
+ .find((r) => r.adults.find((traveler) => traveler.id === formik.values.mainBookerId))
243
+ ?.adults.find((traveler) => traveler.id === formik.values.mainBookerId);
244
+
245
+ const handleAgentChange = (value: string) => {
246
+ const filteredAgents = typeaheadAgents.filter((x) => x.value.toLocaleLowerCase().indexOf(value.toLocaleLowerCase()) > -1);
247
+
248
+ setFilteredAgents(filteredAgents);
249
+ formik.setFieldValue('travelAgentName', value);
250
+ };
251
+
252
+ const handleAgentSelect = (key: string) => {
253
+ const agent = typeaheadAgents.find((x) => x.key === key);
254
+
255
+ formik.setValues({
256
+ ...formik.values,
257
+ travelAgentId: Number(agent?.key),
258
+ travelAgentName: agent?.value ?? ''
259
+ });
260
+
261
+ let bookingType = 'b2b2c';
262
+ if (agentAdressId && agentAdressId != 0) {
263
+ bookingType = 'b2b';
264
+ }
265
+ dispatch(setBookingType(bookingType));
266
+ };
267
+
268
+ const handleAgentClear = () => {
269
+ formik.setValues({
270
+ ...formik.values,
271
+ travelAgentId: 0,
272
+ travelAgentName: ''
273
+ });
274
+
275
+ dispatch(setBookingType('b2c'));
276
+ };
277
+
278
+ const handleAddTraveler = (roomIndex: number) => {
279
+ const rooms = [...formik.values.rooms];
280
+ const newAdult = {
281
+ id: Date.now(),
282
+ firstName: '',
283
+ lastName: '',
284
+ birthDate: '',
285
+ gender: ''
286
+ };
287
+ rooms[roomIndex] = {
288
+ ...rooms[roomIndex],
289
+ adults: [...rooms[roomIndex].adults, newAdult]
290
+ };
291
+ formik.setFieldValue('rooms', rooms);
292
+ };
293
+
294
+ const handleRemoveTraveler = (roomIndex: number, travelerIndex: number) => {
295
+ const rooms = [...formik.values.rooms];
296
+ const adults = [...rooms[roomIndex].adults];
297
+ if (adults.length <= 1) {
298
+ return;
299
+ }
300
+ adults.splice(travelerIndex, 1);
301
+ rooms[roomIndex] = {
302
+ ...rooms[roomIndex],
303
+ adults
304
+ };
305
+ formik.setFieldValue('rooms', rooms);
306
+ };
307
+
308
+ const handleAddRoom = () => {
309
+ const rooms = [...formik.values.rooms];
310
+ const newAdult = {
311
+ id: Date.now(),
312
+ firstName: '',
313
+ lastName: '',
314
+ birthDate: '',
315
+ gender: ''
316
+ };
317
+ rooms.push({ adults: [newAdult], children: [] });
318
+ formik.setFieldValue('rooms', rooms);
319
+ };
320
+
321
+ const handleRemoveRoom = (roomIndex: number) => {
322
+ const rooms = [...formik.values.rooms];
323
+ rooms.splice(roomIndex, 1);
324
+ formik.setFieldValue('rooms', rooms);
325
+ };
326
+
327
+ const toggleAgent = (value: boolean) => {
328
+ setShowAgents(value);
329
+
330
+ if (!value) {
331
+ handleAgentClear();
332
+ setFilteredAgents([]);
333
+ }
334
+ };
335
+
336
+ const goPrevious = () => {
337
+ dispatch(setCurrentStep(OPTIONS_FORM_STEP));
338
+ };
339
+
340
+ const flatErrors: Record<string, string> = flat(formik.errors);
341
+ const errorKeys = Object.keys(flatErrors).filter((key) => get(formik.touched, key));
342
+
343
+ const hasVisibleError = (key: string) => get(formik.errors, key) && get(formik.touched, key);
344
+
345
+ const getControl = (type: string, value: Traveler, name: string) => {
346
+ switch (type) {
347
+ case 'gender': {
348
+ return <GenderControl translations={translations} value={value} formik={formik} name={name} />;
349
+ }
350
+ case 'firstName': {
351
+ return (
352
+ <LabeledInput
353
+ hasError={hasVisibleError(name)}
354
+ extraClassName="form__group--md-33"
355
+ label={translations.TRAVELERS_FORM.FIRST_NAME}
356
+ required
357
+ name={name}
358
+ onChange={formik.handleChange}
359
+ onBlur={formik.handleBlur}
360
+ value={value.firstName}
361
+ />
362
+ );
363
+ }
364
+ case 'lastName': {
365
+ return (
366
+ <LabeledInput
367
+ hasError={hasVisibleError(name)}
368
+ extraClassName="form__group--md-33"
369
+ label={translations.TRAVELERS_FORM.LAST_NAME}
370
+ required
371
+ name={name}
372
+ onChange={formik.handleChange}
373
+ onBlur={formik.handleBlur}
374
+ value={value.lastName}
375
+ />
376
+ );
377
+ }
378
+ case 'birthDate': {
379
+ return (
380
+ <LabeledInput
381
+ type="date"
382
+ hasError={hasVisibleError(name)}
383
+ extraClassName="form__group--md-33"
384
+ label={translations.TRAVELERS_FORM.BIRTHDATE}
385
+ required
386
+ name={name}
387
+ onChange={formik.handleChange}
388
+ onBlur={formik.handleBlur}
389
+ value={value.birthDate}
390
+ />
391
+ );
392
+ }
393
+ case 'country': {
394
+ return (
395
+ <LabeledSelect
396
+ hasError={hasVisibleError('country')}
397
+ label={translations.TRAVELERS_FORM.COUNTRY}
398
+ required
399
+ name="country"
400
+ onChange={formik.handleChange}
401
+ onBlur={formik.handleBlur}
402
+ value={formik.values.country}
403
+ options={[
404
+ {
405
+ key: 'empty',
406
+ value: undefined,
407
+ label: translations.TRAVELERS_FORM.SELECT_COUNTRY
408
+ },
409
+ ...(showAllCountries
410
+ ? countries?.map((country) => ({
411
+ key: country.iso2,
412
+ value: country.iso2,
413
+ label: country.name
414
+ })) ?? []
415
+ : settings.travellers?.countries?.map((country) => ({
416
+ key: country.iso2,
417
+ value: country.iso2,
418
+ label: country.name
419
+ })) ?? [])
420
+ ]}
421
+ />
422
+ );
423
+ }
424
+ case 'phone': {
425
+ return (
426
+ <PhoneInput
427
+ countries={settings.travellers?.countries ?? []}
428
+ countryIso2={formik.values.country}
429
+ hasError={hasVisibleError('phone')}
430
+ label={translations.TRAVELERS_FORM.PHONE}
431
+ required
432
+ name="phone"
433
+ onChange={formik.handleChange}
434
+ onBlur={formik.handleBlur}
435
+ value={formik.values.phone}
436
+ />
437
+ );
438
+ }
439
+ case 'email': {
440
+ return (
441
+ <>
442
+ <LabeledInput
443
+ type="email"
444
+ hasError={hasVisibleError('email')}
445
+ extraClassName="form__group--md-33"
446
+ label={translations.TRAVELERS_FORM.EMAIL}
447
+ required
448
+ name="email"
449
+ onChange={formik.handleChange}
450
+ onBlur={formik.handleBlur}
451
+ value={formik.values.email}
452
+ />
453
+ <LabeledInput
454
+ type="email"
455
+ hasError={hasVisibleError('emailConfirmation')}
456
+ extraClassName="form__group--md-33"
457
+ label={translations.TRAVELERS_FORM.REPEAT_EMAIL}
458
+ required
459
+ name="emailConfirmation"
460
+ onChange={formik.handleChange}
461
+ onBlur={formik.handleBlur}
462
+ value={formik.values.emailConfirmation}
463
+ />
464
+ </>
465
+ );
466
+ }
467
+ }
468
+ };
469
+
470
+ return (
471
+ <form
472
+ className="form form__travelers"
473
+ name="booking--travellers"
474
+ id="booking--travellers"
475
+ noValidate
476
+ onSubmit={formik.handleSubmit}
477
+ onReset={formik.handleReset}>
478
+ {useCompactForm ? (
479
+ <div className="form__travelers__wrapper">
480
+ {formik.values.rooms.map((room, rIndex) => (
481
+ <div key={rIndex}>
482
+ {formik.values.rooms.length > 1 && (
483
+ <div className="form__region">
484
+ <div className="form__region-header">
485
+ <h5 className="form__region-heading">
486
+ {translations.SHARED.ROOM} {rIndex + 1}
487
+ </h5>
488
+ <p className="form__region-label">
489
+ {compact([
490
+ room.adults.length,
491
+ room.adults.length === 1 && ` ${translations.TRAVELERS_FORM.ADULT}`,
492
+ room.adults.length > 1 && ` ${translations.TRAVELERS_FORM.ADULTS}`,
493
+ room.adults && room.adults.length && room.children && room.children.length && ', ',
494
+ room.children.length,
495
+ room.children.length === 1 && ` ${translations.TRAVELERS_FORM.CHILD}`,
496
+ room.children.length > 1 && ` ${translations.TRAVELERS_FORM.CHILDREN}`
497
+ ]).join('')}
498
+ </p>
499
+ </div>
500
+ </div>
501
+ )}
502
+ {room.adults.map((travelerValues, index) => (
503
+ <div className="form__region" key={travelerValues.id}>
504
+ <div className="form__region-header">
505
+ <h5 className="form__region-heading">
506
+ {translations.TRAVELERS_FORM.TRAVELER} {index + 1}
507
+ </h5>
508
+ <p className="form__region-label">{translations.TRAVELERS_FORM.ADULT}</p>
509
+
510
+ <div className="radiobutton">
511
+ <label className="radiobutton__label">
512
+ <input
513
+ type="radio"
514
+ name="mainBookerId"
515
+ onChange={handleMainBookerChange}
516
+ onBlur={formik.handleBlur}
517
+ value={travelerValues.id}
518
+ checked={formik.values.mainBookerId === travelerValues.id}
519
+ className="radiobutton__input"
520
+ />
521
+ {translations.TRAVELERS_FORM.MAIN_BOOKER}
522
+ </label>
523
+ </div>
524
+ </div>
525
+ <div className="form__row">
526
+ <LabeledInput
527
+ hasError={hasVisibleError(`rooms[${rIndex}].adults[${index}].age`)}
528
+ extraClassName="form__group--md-33"
529
+ label={translations.TRAVELERS_FORM.AGE}
530
+ required
531
+ name={`rooms[${rIndex}].adults[${index}].age`}
532
+ onChange={formik.handleChange}
533
+ onBlur={formik.handleBlur}
534
+ value={travelerValues.age}
535
+ />
536
+ </div>
537
+ </div>
538
+ ))}
539
+ {room.children.map((travelerValues, index) => (
540
+ <div className="form__region" key={travelerValues.id}>
541
+ <div className="form__region-header">
542
+ <h5 className="form__region-heading">
543
+ {translations.TRAVELERS_FORM.TRAVELER} {room.adults.length + index + 1}
544
+ </h5>
545
+ <p className="form__region-label">{translations.TRAVELERS_FORM.CHILD}</p>
546
+ </div>
547
+ <div className="form__row">
548
+ <LabeledInput
549
+ hasError={hasVisibleError(`rooms[${rIndex}].children[${index}].age`)}
550
+ extraClassName="form__group--md-33"
551
+ label={translations.TRAVELERS_FORM.AGE}
552
+ required
553
+ name={`rooms[${rIndex}].children[${index}].age`}
554
+ onChange={formik.handleChange}
555
+ onBlur={formik.handleBlur}
556
+ value={travelerValues.age}
557
+ />
558
+ </div>
559
+ </div>
560
+ ))}
561
+ </div>
562
+ ))}
563
+ </div>
564
+ ) : (
565
+ <>
566
+ <div className="form__travelers__wrapper">
567
+ {/* map each room */}
568
+ {formik.values.rooms.map((room, rIndex) => (
569
+ <div key={rIndex}>
570
+ {formik.values.rooms.length > 1 && (
571
+ <div className="form__region">
572
+ <div className="form__region-header">
573
+ <h5 className="form__region-heading">
574
+ {translations.SHARED.ROOM} {rIndex + 1}
575
+ </h5>
576
+ <p className="form__region-label">
577
+ {compact([
578
+ room.adults.length,
579
+ room.adults.length === 1 && ` ${translations.TRAVELERS_FORM.ADULT}`,
580
+ room.adults.length > 1 && ` ${translations.TRAVELERS_FORM.ADULTS}`,
581
+ room.adults && room.adults.length && room.children && room.children.length && ', ',
582
+ room.children.length,
583
+ room.children.length === 1 && ` ${translations.TRAVELERS_FORM.CHILD}`,
584
+ room.children.length > 1 && ` ${translations.TRAVELERS_FORM.CHILDREN}`
585
+ ]).join('')}
586
+ </p>
587
+ </div>
588
+ {travelersFirstStep && formik.values.rooms.length > 1 && (
589
+ <button type="button" className="cta cta--secondary" onClick={() => handleRemoveRoom(rIndex)}>
590
+ Verwijder reisgezelschap
591
+ </button>
592
+ )}
593
+ </div>
594
+ )}
595
+ {/* map adults here for the room */}
596
+ {room.adults.map((travelerValues, index) => (
597
+ <div className="form__region" key={travelerValues.id}>
598
+ <div className="form__region-header">
599
+ <h5 className="form__region-heading">
600
+ {translations.TRAVELERS_FORM.TRAVELER} {index + 1}
601
+ </h5>
602
+ <p className="form__region-label">{translations.TRAVELERS_FORM.ADULT}</p>
603
+
604
+ <div className="radiobutton">
605
+ <label className="radiobutton__label">
606
+ <input
607
+ type="radio"
608
+ name="mainBookerId"
609
+ onChange={handleMainBookerChange}
610
+ onBlur={formik.handleBlur}
611
+ value={travelerValues.id}
612
+ checked={formik.values.mainBookerId === travelerValues.id}
613
+ className="radiobutton__input"
614
+ />
615
+ {translations.TRAVELERS_FORM.MAIN_BOOKER}
616
+ </label>
617
+ </div>
618
+ </div>
619
+ {settings.travellers.formFields?.length ? (
620
+ <>
621
+ <div className="travelers-form__grid">
622
+ {settings.travellers.formFields.map((field, fIndex) => (
623
+ <div key={fIndex} className={`control control--${field.type}`}>
624
+ {getControl(field.type, travelerValues, `rooms[${rIndex}].adults[${index}].${field.type}`)}
625
+ </div>
626
+ ))}
627
+ </div>
628
+ </>
629
+ ) : (
630
+ <>
631
+ <div className="form__row">
632
+ <div className={buildClassName(['form__group', hasVisibleError(`rooms[${rIndex}].adults[${index}].gender`) && 'form__group--error'])}>
633
+ <label className="form__label">{translations.TRAVELERS_FORM.GENDER_ID} *</label>
634
+ <div className="radiobutton-group">
635
+ <div className="radiobutton">
636
+ <label className="radiobutton__label">
637
+ <input
638
+ type="radio"
639
+ className="radiobutton__input"
640
+ name={`rooms[${rIndex}].adults[${index}].gender`}
641
+ onChange={formik.handleChange}
642
+ onBlur={formik.handleBlur}
643
+ value="m"
644
+ checked={travelerValues.gender === 'm'}
645
+ />
646
+ {translations.TRAVELERS_FORM.MALE_GENDER}
647
+ </label>
648
+ </div>
649
+
650
+ <div className="radiobutton">
651
+ <label className="radiobutton__label">
652
+ <input
653
+ type="radio"
654
+ className="radiobutton__input"
655
+ name={`rooms[${rIndex}].adults[${index}].gender`}
656
+ onChange={formik.handleChange}
657
+ onBlur={formik.handleBlur}
658
+ value="f"
659
+ checked={travelerValues.gender === 'f'}
660
+ />
661
+ {translations.TRAVELERS_FORM.FEMALE_GENDER}
662
+ </label>
663
+ </div>
664
+
665
+ {/* <div className="radiobutton">
666
+ <label className="radiobutton__label">
667
+ <input
668
+ type="radio"
669
+ className="radiobutton__input"
670
+ name={`rooms[${rIndex}].adults[${index}].gender`}
671
+ onChange={formik.handleChange}
672
+ onBlur={formik.handleBlur}
673
+ value="x"
674
+ checked={travelerValues.gender === 'x'}
675
+ />
676
+ {translations.TRAVELERS_FORM.OTHER}
677
+ </label>
678
+ </div> */}
679
+ </div>
680
+ </div>
681
+ </div>
682
+ <div className="form__row">
683
+ <LabeledInput
684
+ hasError={hasVisibleError(`rooms[${rIndex}].adults[${index}].firstName`)}
685
+ extraClassName="form__group--md-33"
686
+ label={translations.TRAVELERS_FORM.FIRST_NAME}
687
+ required
688
+ name={`rooms[${rIndex}].adults[${index}].firstName`}
689
+ onChange={formik.handleChange}
690
+ onBlur={formik.handleBlur}
691
+ value={travelerValues.firstName}
692
+ />
693
+ <LabeledInput
694
+ hasError={hasVisibleError(`rooms[${rIndex}].adults[${index}].lastName`)}
695
+ extraClassName="form__group--md-33"
696
+ label={translations.TRAVELERS_FORM.LAST_NAME}
697
+ required
698
+ name={`rooms[${rIndex}].adults[${index}].lastName`}
699
+ onChange={formik.handleChange}
700
+ onBlur={formik.handleBlur}
701
+ value={travelerValues.lastName}
702
+ />
703
+ <LabeledInput
704
+ type="date"
705
+ hasError={hasVisibleError(`rooms[${rIndex}].adults[${index}].birthDate`)}
706
+ extraClassName="form__group--md-33"
707
+ label={translations.TRAVELERS_FORM.BIRTHDATE}
708
+ required
709
+ name={`rooms[${rIndex}].adults[${index}].birthDate`}
710
+ onChange={formik.handleChange}
711
+ onBlur={formik.handleBlur}
712
+ value={travelerValues.birthDate}
713
+ />
714
+ </div>
715
+ {travelersFirstStep && room.adults.length > 1 && (
716
+ <button type="button" className="cta cta--secondary" onClick={() => handleRemoveTraveler(rIndex, index)}>
717
+ {translations.TRAVELERS_FORM.REMOVE_TRAVELER}
718
+ </button>
719
+ )}
720
+ </>
721
+ )}
722
+ </div>
723
+ ))}
724
+ {room.children.map((travelerValues, index) => (
725
+ <div className="form__region" key={travelerValues.id}>
726
+ <div className="form__region-header">
727
+ <h5 className="form__region-heading">
728
+ {translations.TRAVELERS_FORM.TRAVELER} {room.adults.length + index + 1}
729
+ </h5>
730
+ <p className="form__region-label">{translations.TRAVELERS_FORM.CHILD}</p>
731
+ </div>
732
+ {settings.travellers.formFields?.length ? (
733
+ <>
734
+ <div className="travelers-form__grid">
735
+ {settings.travellers.formFields.map((field, fIndex) => (
736
+ <div key={fIndex} className={`control control--${field.type}`}>
737
+ {getControl(field.type, travelerValues, `rooms[${rIndex}].children[${index}].${field.type}`)}
738
+ </div>
739
+ ))}
740
+ </div>
741
+ </>
742
+ ) : (
743
+ <>
744
+ <div className="form__row">
745
+ <div
746
+ className={buildClassName(['form__group', hasVisibleError(`rooms[${rIndex}].children[${index}].gender`) && 'form__group--error'])}>
747
+ <label className="form__label">{translations.TRAVELERS_FORM.GENDER_ID} *</label>
748
+ <div className="radiobutton-group">
749
+ <div className="radiobutton">
750
+ <label className="radiobutton__label">
751
+ <input
752
+ type="radio"
753
+ className="radiobutton__input"
754
+ name={`rooms[${rIndex}].children[${index}].gender`}
755
+ onChange={formik.handleChange}
756
+ onBlur={formik.handleBlur}
757
+ value="m"
758
+ checked={travelerValues.gender === 'm'}
759
+ />
760
+ {translations.TRAVELERS_FORM.MALE_GENDER}
761
+ </label>
762
+ </div>
763
+
764
+ <div className="radiobutton">
765
+ <label className="radiobutton__label">
766
+ <input
767
+ type="radio"
768
+ className="radiobutton__input"
769
+ name={`rooms[${rIndex}].children[${index}].gender`}
770
+ onChange={formik.handleChange}
771
+ onBlur={formik.handleBlur}
772
+ value="f"
773
+ checked={travelerValues.gender === 'f'}
774
+ />
775
+ {translations.TRAVELERS_FORM.FEMALE_GENDER}
776
+ </label>
777
+ </div>
778
+
779
+ {/* <div className="radiobutton">
780
+ <label className="radiobutton__label">
781
+ <input
782
+ type="radio"
783
+ className="radiobutton__input"
784
+ name={`rooms[${rIndex}].children[${index}].gender`}
785
+ onChange={formik.handleChange}
786
+ onBlur={formik.handleBlur}
787
+ value="x"
788
+ checked={travelerValues.gender === 'x'}
789
+ />
790
+ {translations.TRAVELERS_FORM.OTHER}
791
+ </label>
792
+ </div> */}
793
+ </div>
794
+ </div>
795
+ </div>
796
+ <div className="form__row">
797
+ <LabeledInput
798
+ hasError={hasVisibleError(`rooms[${rIndex}].children[${index}].firstName`)}
799
+ extraClassName="form__group--md-33"
800
+ label={translations.TRAVELERS_FORM.FIRST_NAME}
801
+ required
802
+ name={`rooms[${rIndex}].children[${index}].firstName`}
803
+ onChange={formik.handleChange}
804
+ onBlur={formik.handleBlur}
805
+ value={travelerValues.firstName}
806
+ />
807
+ <LabeledInput
808
+ hasError={hasVisibleError(`rooms[${rIndex}].children[${index}].lastName`)}
809
+ extraClassName="form__group--md-33"
810
+ label={translations.TRAVELERS_FORM.LAST_NAME}
811
+ required
812
+ name={`rooms[${rIndex}].children[${index}].lastName`}
813
+ onChange={formik.handleChange}
814
+ onBlur={formik.handleBlur}
815
+ value={travelerValues.lastName}
816
+ />
817
+ <LabeledInput
818
+ type="date"
819
+ hasError={hasVisibleError(`rooms[${rIndex}].children[${index}].birthDate`)}
820
+ extraClassName="form__group--md-33"
821
+ label={translations.TRAVELERS_FORM.BIRTHDATE}
822
+ required
823
+ name={`rooms[${rIndex}].children[${index}].birthDate`}
824
+ onChange={formik.handleChange}
825
+ onBlur={formik.handleBlur}
826
+ value={travelerValues.birthDate}
827
+ />
828
+ </div>
829
+ </>
830
+ )}
831
+ </div>
832
+ ))}
833
+ {travelersFirstStep && (
834
+ <div className="form__region">
835
+ <button type="button" className="cta cta--select" onClick={() => handleAddTraveler(rIndex)}>
836
+ {translations.TRAVELERS_FORM.ADD_TRAVELER}
837
+ </button>
838
+ </div>
839
+ )}
840
+ </div>
841
+ ))}
842
+
843
+ {bookingType != 'b2b' || settings.travellers?.mainBookerFormFields?.length ? (
844
+ <div className="form__region">
845
+ <div className="form__region-header">
846
+ <h5 className="form__region-heading">{translations.TRAVELERS_FORM.MAIN_BOOKER}</h5>
847
+ <p className="form__region-label">
848
+ {compact([
849
+ compact([mainBooker?.firstName, mainBooker?.lastName]).join(' '),
850
+ mainBooker?.birthDate && format(parse(mainBooker.birthDate, 'yyyy-MM-dd', new Date()), 'dd-MM-yyyy')
851
+ ]).join(', ')}
852
+ </p>
853
+ </div>
854
+ <>
855
+ {settings.travellers?.mainBookerFormFields?.length ? (
856
+ <>
857
+ <div className="main-booker-form__grid">
858
+ {settings.travellers.mainBookerFormFields.map((field, fIndex) => (
859
+ <div key={fIndex} className={`control control--${field.type}`}>
860
+ {getControl(field.type, {} as Traveler, field.type)}
861
+ </div>
862
+ ))}
863
+ </div>
864
+ </>
865
+ ) : (
866
+ <>
867
+ <div className="form__twocolumn">
868
+ <div className="form__twocolumn-column">
869
+ <div className="form__row">
870
+ <LabeledInput
871
+ hasError={hasVisibleError('street')}
872
+ extraClassName="form__group--50 form__group--sm-60"
873
+ label={translations.TRAVELERS_FORM.STREET}
874
+ required
875
+ name="street"
876
+ onChange={formik.handleChange}
877
+ onBlur={formik.handleBlur}
878
+ value={formik.values.street}
879
+ />
880
+ <LabeledInput
881
+ hasError={hasVisibleError('houseNumber')}
882
+ extraClassName="form__group--30 form__group--sm-20"
883
+ label={translations.TRAVELERS_FORM.HOUSE_NUMBER}
884
+ required
885
+ name="houseNumber"
886
+ onChange={formik.handleChange}
887
+ onBlur={formik.handleBlur}
888
+ value={formik.values.houseNumber}
889
+ />
890
+ <LabeledInput
891
+ hasError={hasVisibleError('box')}
892
+ extraClassName="form__group--20"
893
+ label={translations.TRAVELERS_FORM.POST_BOX}
894
+ name="box"
895
+ onChange={formik.handleChange}
896
+ onBlur={formik.handleBlur}
897
+ value={formik.values.box}
898
+ />
899
+ </div>
900
+ </div>
901
+ <div className="form__twocolumn-column">
902
+ <div className="form__row">
903
+ <LabeledInput
904
+ hasError={hasVisibleError('zipCode')}
905
+ extraClassName="form__group--40 form__group--sm-20"
906
+ label={translations.TRAVELERS_FORM.ZIPCODE}
907
+ required
908
+ name="zipCode"
909
+ onChange={formik.handleChange}
910
+ onBlur={formik.handleBlur}
911
+ value={formik.values.zipCode}
912
+ />
913
+ <LabeledInput
914
+ hasError={hasVisibleError('place')}
915
+ extraClassName="form__group--60 form__group--sm-40"
916
+ label={translations.TRAVELERS_FORM.CITY}
917
+ required
918
+ name="place"
919
+ onChange={formik.handleChange}
920
+ onBlur={formik.handleBlur}
921
+ value={formik.values.place}
922
+ />
923
+ <LabeledSelect
924
+ hasError={hasVisibleError('country')}
925
+ extraClassName="form__group--sm-40"
926
+ label={translations.TRAVELERS_FORM.COUNTRY}
927
+ required
928
+ name="country"
929
+ onChange={formik.handleChange}
930
+ onBlur={formik.handleBlur}
931
+ value={formik.values.country}
932
+ options={[
933
+ {
934
+ key: 'empty',
935
+ value: undefined,
936
+ label: translations.TRAVELERS_FORM.SELECT_COUNTRY
937
+ },
938
+ ...(showAllCountries
939
+ ? countries?.map((country) => ({
940
+ key: country.iso2,
941
+ value: country.iso2,
942
+ label: country.name
943
+ })) ?? []
944
+ : [
945
+ {
946
+ key: 'be',
947
+ value: 'be',
948
+ label: translations.TRAVELERS_FORM.COUNTRIES.BELGIUM
949
+ },
950
+ {
951
+ key: 'nl',
952
+ value: 'nl',
953
+ label: translations.TRAVELERS_FORM.COUNTRIES.NETHERLANDS
954
+ },
955
+ {
956
+ key: 'fr',
957
+ value: 'fr',
958
+ label: translations.TRAVELERS_FORM.COUNTRIES.FRANCE
959
+ }
960
+ ])
961
+ ]}
962
+ />
963
+ </div>
964
+ </div>
965
+ </div>
966
+ <div className="form__row">
967
+ <LabeledInput
968
+ hasError={hasVisibleError('phone')}
969
+ extraClassName="form__group--md-33"
970
+ label={translations.TRAVELERS_FORM.PHONE}
971
+ required
972
+ name="phone"
973
+ onChange={formik.handleChange}
974
+ onBlur={formik.handleBlur}
975
+ value={formik.values.phone}
976
+ />
977
+ <LabeledInput
978
+ type="email"
979
+ hasError={hasVisibleError('email')}
980
+ extraClassName="form__group--md-33"
981
+ label={translations.TRAVELERS_FORM.EMAIL}
982
+ required
983
+ name="email"
984
+ onChange={formik.handleChange}
985
+ onBlur={formik.handleBlur}
986
+ value={formik.values.email}
987
+ />
988
+ <LabeledInput
989
+ type="email"
990
+ hasError={hasVisibleError('emailConfirmation')}
991
+ extraClassName="form__group--md-33"
992
+ label={translations.TRAVELERS_FORM.REPEAT_EMAIL}
993
+ required
994
+ name="emailConfirmation"
995
+ onChange={formik.handleChange}
996
+ onBlur={formik.handleBlur}
997
+ value={formik.values.emailConfirmation}
998
+ />
999
+ </div>
1000
+ </>
1001
+ )}
1002
+ </>
1003
+ </div>
1004
+ ) : (
1005
+ <div className="form__region">
1006
+ <div className="form__row">
1007
+ <LabeledInput
1008
+ hasError={hasVisibleError('phone')}
1009
+ extraClassName="form__group--md-33"
1010
+ label={translations.TRAVELERS_FORM.PHONE}
1011
+ required
1012
+ name="phone"
1013
+ onChange={formik.handleChange}
1014
+ onBlur={formik.handleBlur}
1015
+ value={formik.values.phone}
1016
+ />
1017
+ </div>
1018
+ </div>
1019
+ )}
1020
+
1021
+ {showAgentSelection && (
1022
+ <div className="form__region">
1023
+ <div className="form__region-header">
1024
+ <h5 className="form__region-heading">{translations.TRAVELERS_FORM.BOOK_WITH_AGENT}</h5>
1025
+ <div className="checkbox" id="cbxChooseOffice">
1026
+ <label className="checkbox__label">
1027
+ <input
1028
+ type="checkbox"
1029
+ name="booking--mainbooker"
1030
+ defaultChecked={showAgents}
1031
+ onClick={() => toggleAgent(!showAgents)}
1032
+ className="checkbox__input"
1033
+ />
1034
+ {translations.TRAVELERS_FORM.CHOOSE_OFFICE}
1035
+ </label>
1036
+ </div>
1037
+ </div>
1038
+ {showAgents && (
1039
+ <div className="form__row form__row--choose-office">
1040
+ <div className={buildClassName(['form__group', 'form__group--icon', hasVisibleError('travelAgentId') && 'form__group--error'])}>
1041
+ <TypeAheadInput
1042
+ value={formik.values.travelAgentName}
1043
+ options={filteredAgents}
1044
+ onChange={handleAgentChange}
1045
+ onSelect={handleAgentSelect}
1046
+ onClear={handleAgentClear}
1047
+ name="travelAgentName"
1048
+ placeholder={translations.TRAVELERS_FORM.CHOOSE_AGENT_PLACEHOLDER}
1049
+ />
1050
+ </div>
1051
+ </div>
1052
+ )}
1053
+ </div>
1054
+ )}
1055
+ </div>
1056
+ {errorKeys.length > 0 && (
1057
+ <div className="form__region form__region--errors">
1058
+ <div className="form__row">
1059
+ <div className="form__group">
1060
+ <p className="form__error-heading">{translations.TRAVELERS_FORM.VALIDATION_MESSAGE}:</p>
1061
+ <ul className="list">
1062
+ {errorKeys.map((key) => (
1063
+ <li key={key}>{get(flatErrors, key)}</li>
1064
+ ))}
1065
+ </ul>
1066
+ </div>
1067
+ </div>
1068
+ </div>
1069
+ )}
1070
+ </>
1071
+ )}
1072
+ {travelersFirstStep && (
1073
+ <div className="booking__navigator">
1074
+ <button type="button" className="cta cta--select" onClick={handleAddRoom}>
1075
+ {translations.TRAVELERS_FORM.ADD_ROOM}
1076
+ </button>
1077
+ </div>
1078
+ )}
1079
+
1080
+ <div className="booking__navigator">
1081
+ {!travelersFirstStep && settings.skipRouter ? (
1082
+ <button type="button" title={translations.STEPS.PREVIOUS} onClick={() => goPrevious()} className="cta cta--secondary">
1083
+ {translations.STEPS.PREVIOUS}
1084
+ </button>
1085
+ ) : !travelersFirstStep ? (
1086
+ <Link
1087
+ to={`${!settings.skipBasePathInRouting ? settings.basePath : ''}${settings.options.pathSuffix}?${bookingQueryString}`}
1088
+ title={translations.STEPS.PREVIOUS}
1089
+ className="cta cta--secondary">
1090
+ {translations.STEPS.PREVIOUS}
1091
+ </Link>
1092
+ ) : null}
1093
+ <button type="submit" title={translations.STEPS.NEXT} className={'cta' + (isUnavailable ? ' cta--disabled' : '')}>
1094
+ {translations.STEPS.NEXT}
1095
+ </button>
1096
+ </div>
1097
+ </form>
1098
+ );
1099
+ };
1100
+
1101
+ export default TravelersForm;