@qite/tide-booking-component 1.4.122 → 1.4.124

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 (706) hide show
  1. package/.claude/settings.local.json +11 -0
  2. package/.husky/pre-commit +22 -1
  3. package/.prettierignore +32 -0
  4. package/.prettierrc +9 -9
  5. package/.vs/ProjectSettings.json +3 -3
  6. package/.vs/VSWorkspaceState.json +5 -5
  7. package/MEMORY.md +97 -0
  8. package/NEXTSTEPS.md +94 -0
  9. package/README.md +26 -24
  10. package/package.json +10 -1
  11. package/rollup.config.js +16 -16
  12. package/src/booking-product/components/age-select.tsx +35 -35
  13. package/src/booking-product/components/amount-input.tsx +51 -51
  14. package/src/booking-product/components/date-range-picker/calendar-day.tsx +46 -46
  15. package/src/booking-product/components/date-range-picker/calendar.tsx +155 -155
  16. package/src/booking-product/components/date-range-picker/index.tsx +185 -185
  17. package/src/booking-product/components/dates.tsx +153 -153
  18. package/src/booking-product/components/footer.tsx +54 -54
  19. package/src/booking-product/components/header.tsx +58 -57
  20. package/src/booking-product/components/list-view.tsx +54 -54
  21. package/src/booking-product/components/product.tsx +447 -379
  22. package/src/booking-product/components/rating.tsx +21 -21
  23. package/src/booking-product/components/rooms.tsx +192 -171
  24. package/src/booking-product/constants.ts +1 -1
  25. package/src/booking-product/index.tsx +21 -21
  26. package/src/booking-product/settings-context.ts +16 -16
  27. package/src/booking-product/types.ts +68 -30
  28. package/src/booking-product/utils/api.ts +26 -26
  29. package/src/booking-product/utils/price.ts +28 -28
  30. package/src/booking-wizard/api-settings-slice.ts +24 -24
  31. package/src/booking-wizard/components/labeled-input.tsx +56 -56
  32. package/src/booking-wizard/components/labeled-select.tsx +54 -54
  33. package/src/booking-wizard/components/message.tsx +21 -21
  34. package/src/booking-wizard/components/multi-range-filter.tsx +99 -99
  35. package/src/booking-wizard/components/phone-input.tsx +146 -146
  36. package/src/booking-wizard/components/print-offer-button.tsx +53 -53
  37. package/src/booking-wizard/components/step-indicator.tsx +36 -36
  38. package/src/booking-wizard/components/step-route.tsx +51 -51
  39. package/src/booking-wizard/declarations.d.ts +4 -4
  40. package/src/booking-wizard/features/booking/api.ts +44 -44
  41. package/src/booking-wizard/features/booking/booking-self-contained.tsx +364 -318
  42. package/src/booking-wizard/features/booking/booking-slice.ts +634 -634
  43. package/src/booking-wizard/features/booking/booking.tsx +388 -344
  44. package/src/booking-wizard/features/booking/constants.ts +16 -16
  45. package/src/booking-wizard/features/booking/selectors.ts +411 -411
  46. package/src/booking-wizard/features/confirmation/confirmation.tsx +46 -46
  47. package/src/booking-wizard/features/error/error.tsx +71 -71
  48. package/src/booking-wizard/features/flight-options/flight-filter.tsx +371 -371
  49. package/src/booking-wizard/features/flight-options/flight-option-flight.tsx +354 -354
  50. package/src/booking-wizard/features/flight-options/flight-option-modal.tsx +211 -211
  51. package/src/booking-wizard/features/flight-options/flight-option.tsx +57 -57
  52. package/src/booking-wizard/features/flight-options/flight-utils.ts +423 -423
  53. package/src/booking-wizard/features/flight-options/index.tsx +170 -170
  54. package/src/booking-wizard/features/price-details/price-details-api.ts +20 -20
  55. package/src/booking-wizard/features/price-details/price-details-slice.ts +79 -79
  56. package/src/booking-wizard/features/price-details/selectors.ts +118 -118
  57. package/src/booking-wizard/features/price-details/util.ts +115 -115
  58. package/src/booking-wizard/features/product-options/no-options.tsx +18 -18
  59. package/src/booking-wizard/features/product-options/none-option.tsx +73 -73
  60. package/src/booking-wizard/features/product-options/option-booking-airline-group.tsx +53 -53
  61. package/src/booking-wizard/features/product-options/option-booking-group.tsx +152 -152
  62. package/src/booking-wizard/features/product-options/option-item.tsx +236 -236
  63. package/src/booking-wizard/features/product-options/option-pax-card.tsx +159 -159
  64. package/src/booking-wizard/features/product-options/option-pax-group.tsx +122 -122
  65. package/src/booking-wizard/features/product-options/option-room.tsx +226 -226
  66. package/src/booking-wizard/features/product-options/option-unit-group.tsx +138 -138
  67. package/src/booking-wizard/features/product-options/option-units-card.tsx +148 -148
  68. package/src/booking-wizard/features/product-options/options-form.tsx +382 -382
  69. package/src/booking-wizard/features/room-options/index.tsx +132 -132
  70. package/src/booking-wizard/features/room-options/room-utils.ts +154 -154
  71. package/src/booking-wizard/features/room-options/room.tsx +123 -123
  72. package/src/booking-wizard/features/room-options/traveler-rooms.tsx +64 -64
  73. package/src/booking-wizard/features/sidebar/index.tsx +89 -89
  74. package/src/booking-wizard/features/sidebar/sidebar-flight.tsx +66 -66
  75. package/src/booking-wizard/features/sidebar/sidebar-util.ts +143 -143
  76. package/src/booking-wizard/features/sidebar/sidebar.tsx +349 -349
  77. package/src/booking-wizard/features/summary/summary-booking-option-pax.tsx +23 -23
  78. package/src/booking-wizard/features/summary/summary-booking-option-unit.tsx +23 -23
  79. package/src/booking-wizard/features/summary/summary-flight.tsx +36 -36
  80. package/src/booking-wizard/features/summary/summary-per-booking-option-group.tsx +60 -60
  81. package/src/booking-wizard/features/summary/summary-per-pax-option-group.tsx +56 -56
  82. package/src/booking-wizard/features/summary/summary-per-unit-option-group.tsx +58 -58
  83. package/src/booking-wizard/features/summary/summary-slice.ts +27 -27
  84. package/src/booking-wizard/features/summary/summary.tsx +19 -3
  85. package/src/booking-wizard/features/travelers-form/controls/gender-control.tsx +60 -60
  86. package/src/booking-wizard/features/travelers-form/travelers-form-slice.ts +157 -157
  87. package/src/booking-wizard/features/travelers-form/travelers-form-util.ts +10 -10
  88. package/src/booking-wizard/features/travelers-form/travelers-form.tsx +181 -175
  89. package/src/booking-wizard/features/travelers-form/type-ahead-input.tsx +85 -85
  90. package/src/booking-wizard/features/travelers-form/validate-form.ts +178 -178
  91. package/src/booking-wizard/index.tsx +27 -27
  92. package/src/booking-wizard/settings-context.ts +64 -64
  93. package/src/booking-wizard/store.ts +26 -26
  94. package/src/booking-wizard/types.ts +17 -0
  95. package/src/booking-wizard/use-offer-printer.ts +108 -108
  96. package/src/content/components/LanguageSwitcher.tsx +158 -158
  97. package/src/content/components/accordion.tsx +30 -30
  98. package/src/content/components/breadcrumb.tsx +67 -67
  99. package/src/content/components/contact.tsx +210 -210
  100. package/src/content/components/faq.tsx +42 -42
  101. package/src/content/components/gallery.tsx +153 -153
  102. package/src/content/components/image-with-text.tsx +119 -119
  103. package/src/content/components/login.tsx +161 -161
  104. package/src/content/components/personal-contact-form.tsx +809 -809
  105. package/src/content/components/slider.tsx +237 -237
  106. package/src/content/error/error.tsx +27 -27
  107. package/src/content/featured-trips/featured-trip-card.tsx +48 -48
  108. package/src/content/featured-trips/index.tsx +19 -19
  109. package/src/content/featured-trips/types.ts +13 -13
  110. package/src/content/features/content-page/content-page-self-contained.tsx +895 -895
  111. package/src/content/footer/index.tsx +159 -159
  112. package/src/content/footer/types.ts +36 -36
  113. package/src/content/header/index.tsx +43 -43
  114. package/src/content/header/types.ts +26 -26
  115. package/src/content/image-card-grid/index.tsx +34 -34
  116. package/src/content/image-card-grid/types.ts +13 -13
  117. package/src/content/image-with-text-section/card.tsx +58 -58
  118. package/src/content/image-with-text-section/index.tsx +22 -22
  119. package/src/content/image-with-text-section/types.ts +20 -20
  120. package/src/content/login/confirm-component.tsx +149 -149
  121. package/src/content/login/index.tsx +70 -70
  122. package/src/content/login/login-component.tsx +159 -159
  123. package/src/content/login/login-services.ts +109 -109
  124. package/src/content/login/reset-password-component.tsx +191 -191
  125. package/src/content/login/types.ts +29 -29
  126. package/src/content/navbar/index.tsx +354 -354
  127. package/src/content/navbar/placeholderData.tsx +173 -173
  128. package/src/content/navbar/types.ts +43 -43
  129. package/src/index.ts +46 -46
  130. package/src/qsm/components/QSMContainer/qsm-container.tsx +671 -671
  131. package/src/qsm/components/date-picker/index.tsx +152 -152
  132. package/src/qsm/components/date-range-picker/calendar-day.tsx +49 -49
  133. package/src/qsm/components/date-range-picker/calendar.tsx +211 -211
  134. package/src/qsm/components/date-range-picker/index.tsx +404 -404
  135. package/src/qsm/components/double-search-input-group/index.tsx +78 -78
  136. package/src/qsm/components/item-picker/index.tsx +65 -65
  137. package/src/qsm/components/mobile-filter-modal/index.tsx +321 -321
  138. package/src/qsm/components/search-input/index.tsx +91 -91
  139. package/src/qsm/components/search-input-group/index.tsx +209 -209
  140. package/src/qsm/components/travel-class-picker/index.tsx +28 -28
  141. package/src/qsm/components/travel-input/index.tsx +241 -241
  142. package/src/qsm/components/travel-input-group/index.tsx +114 -114
  143. package/src/qsm/components/travel-nationality-picker/index.tsx +28 -28
  144. package/src/qsm/components/travel-type-picker/index.tsx +28 -28
  145. package/src/qsm/index.tsx +26 -26
  146. package/src/qsm/qsm-configuration-context.ts +31 -31
  147. package/src/qsm/store/qsm-slice.ts +282 -282
  148. package/src/qsm/store/qsm-store.ts +13 -13
  149. package/src/qsm/types.ts +110 -110
  150. package/src/search-results/components/book-packaging-entry/index.tsx +266 -266
  151. package/src/search-results/components/book-packaging-entry/wl-sidebar.tsx +173 -173
  152. package/src/search-results/components/excursions/day-by-day-excursions.tsx +168 -168
  153. package/src/search-results/components/excursions/excursion-details.tsx +340 -340
  154. package/src/search-results/components/excursions/excursion-results.tsx +186 -186
  155. package/src/search-results/components/filters/filters.tsx +229 -229
  156. package/src/search-results/components/filters/flight-filters.tsx +671 -671
  157. package/src/search-results/components/flight/flight-banner.tsx +35 -35
  158. package/src/search-results/components/flight/flight-card.tsx +38 -38
  159. package/src/search-results/components/flight/flight-leg.tsx +61 -61
  160. package/src/search-results/components/flight/flight-path.tsx +23 -23
  161. package/src/search-results/components/flight/flight-results.tsx +208 -208
  162. package/src/search-results/components/flight/flight-search-context/index.tsx +628 -628
  163. package/src/search-results/components/flight/flight-selection/independent-flight-option.tsx +168 -168
  164. package/src/search-results/components/flight/flight-selection/independent-flight-selection.tsx +184 -184
  165. package/src/search-results/components/flight/flight-selection/index.tsx +19 -19
  166. package/src/search-results/components/flight/flight-selection/paired-flight-option.tsx +255 -255
  167. package/src/search-results/components/flight/flight-selection/paired-flight-selection.tsx +38 -38
  168. package/src/search-results/components/group-tour/group-tour-card.tsx +105 -105
  169. package/src/search-results/components/group-tour/group-tour-results.tsx +62 -62
  170. package/src/search-results/components/hotel/hotel-accommodation-results.tsx +244 -244
  171. package/src/search-results/components/hotel/hotel-card.tsx +110 -110
  172. package/src/search-results/components/item-picker/index.tsx +81 -81
  173. package/src/search-results/components/itinerary/full-itinerary.tsx +374 -374
  174. package/src/search-results/components/itinerary/index.tsx +437 -437
  175. package/src/search-results/components/multi-range-filter.tsx +104 -104
  176. package/src/search-results/components/round-trip/round-trip-results.tsx +199 -199
  177. package/src/search-results/components/search-results-container/flight-search-results.tsx +137 -137
  178. package/src/search-results/components/search-results-container/search-results-container.tsx +1764 -1764
  179. package/src/search-results/components/spinner/spinner.tsx +24 -24
  180. package/src/search-results/components/tab-views/index.tsx +53 -53
  181. package/src/search-results/features/flights/flight-search-results-self-contained.tsx +294 -294
  182. package/src/search-results/features/hotels/hotel-flight-search-results-self-contained.tsx +143 -143
  183. package/src/search-results/features/hotels/hotel-search-results-self-contained.tsx +220 -220
  184. package/src/search-results/features/roundtrips/roundtrip-search-results-self-contained.tsx +65 -65
  185. package/src/search-results/index.tsx +25 -25
  186. package/src/search-results/search-results-configuration-context.ts +6 -6
  187. package/src/search-results/store/search-results-selectors.ts +84 -84
  188. package/src/search-results/store/search-results-slice.ts +351 -351
  189. package/src/search-results/store/search-results-store.ts +13 -13
  190. package/src/search-results/types.ts +266 -266
  191. package/src/search-results/utils/flight-utils.ts +98 -98
  192. package/src/search-results/utils/packaging-utils.ts +75 -75
  193. package/src/search-results/utils/query-utils.ts +153 -153
  194. package/src/search-results/utils/search-results-utils.ts +538 -538
  195. package/src/shared/booking/booking-panel.tsx +25 -25
  196. package/src/shared/booking/product-card.tsx +23 -23
  197. package/src/shared/booking/shared-confirmation.tsx +105 -105
  198. package/src/shared/booking/shared-sidebar.tsx +432 -432
  199. package/src/shared/booking/step-indicators.tsx +30 -30
  200. package/src/shared/booking/summary.tsx +382 -382
  201. package/src/shared/booking/travelers-form.tsx +874 -874
  202. package/src/shared/components/flyin/accommodation-flyin.tsx +424 -424
  203. package/src/shared/components/flyin/flights-flyin.tsx +508 -508
  204. package/src/shared/components/flyin/flyin.tsx +241 -241
  205. package/src/shared/components/flyin/group-tour-flyin.tsx +294 -294
  206. package/src/shared/components/flyin/packaging-flights-flyin.tsx +171 -171
  207. package/src/shared/components/icon.tsx +1114 -1114
  208. package/src/shared/components/loader.tsx +16 -16
  209. package/src/shared/translations/ar-SA.json +398 -398
  210. package/src/shared/translations/da-DK.json +398 -398
  211. package/src/shared/translations/de-DE.json +398 -398
  212. package/src/shared/translations/en-GB.json +402 -402
  213. package/src/shared/translations/es-ES.json +398 -398
  214. package/src/shared/translations/fr-BE.json +402 -402
  215. package/src/shared/translations/fr-FR.json +398 -398
  216. package/src/shared/translations/is-IS.json +398 -398
  217. package/src/shared/translations/it-IT.json +398 -398
  218. package/src/shared/translations/ja-JP.json +398 -398
  219. package/src/shared/translations/nl-BE.json +402 -402
  220. package/src/shared/translations/nl-NL.json +398 -398
  221. package/src/shared/translations/no-NO.json +398 -398
  222. package/src/shared/translations/pl-PL.json +398 -398
  223. package/src/shared/translations/pt-PT.json +398 -398
  224. package/src/shared/translations/sv-SE.json +398 -398
  225. package/src/shared/types.ts +31 -31
  226. package/src/shared/utils/booking-summary.tsx +57 -57
  227. package/src/shared/utils/class-util.ts +7 -7
  228. package/src/shared/utils/localization-util.ts +316 -301
  229. package/src/shared/utils/query-string-util.ts +91 -91
  230. package/src/shared/utils/tide-api-utils.ts +42 -42
  231. package/src/shared/utils/use-media-query-util.ts +19 -19
  232. package/styles/abstracts/_mixins.scss +74 -74
  233. package/styles/abstracts/_variables.scss +57 -57
  234. package/styles/base/_fonts.scss +2 -2
  235. package/styles/base/_normalize.scss +227 -227
  236. package/styles/base/_typography.scss +35 -35
  237. package/styles/booking-joker-variables.scss +596 -596
  238. package/styles/booking-product-variables.scss +330 -330
  239. package/styles/booking-product.scss +438 -438
  240. package/styles/booking-qsm-variables.scss +501 -501
  241. package/styles/booking-qsm.scss +52 -52
  242. package/styles/booking-search-results-variables.scss +728 -728
  243. package/styles/booking-search-results.scss +53 -53
  244. package/styles/booking-wizard-variables.scss +603 -603
  245. package/styles/booking-wizard.scss +61 -61
  246. package/styles/components/_accordion.scss +67 -67
  247. package/styles/components/_animations.scss +39 -39
  248. package/styles/components/_base.scss +107 -107
  249. package/styles/components/_booking.scss +906 -906
  250. package/styles/components/_breadcrumb.scss +92 -92
  251. package/styles/components/_button.scss +238 -238
  252. package/styles/components/_checkbox.scss +230 -230
  253. package/styles/components/_contact.scss +255 -239
  254. package/styles/components/_content.scss +336 -336
  255. package/styles/components/_cta.scss +238 -238
  256. package/styles/components/_date-list.scss +41 -41
  257. package/styles/components/_date-range-picker.scss +223 -223
  258. package/styles/components/_decrement-increment.scss +35 -35
  259. package/styles/components/_dropdown.scss +77 -77
  260. package/styles/components/_error.scss +50 -50
  261. package/styles/components/_faq.scss +30 -30
  262. package/styles/components/_flight-option.scss +1432 -1432
  263. package/styles/components/_flyin.scss +830 -830
  264. package/styles/components/_footer.scss +135 -135
  265. package/styles/components/_form.scss +1693 -1693
  266. package/styles/components/_gallery.scss +317 -317
  267. package/styles/components/_header.scss +113 -113
  268. package/styles/components/_image-with-text.scss +206 -206
  269. package/styles/components/_img-slider.scss +175 -175
  270. package/styles/components/_info-message.scss +75 -75
  271. package/styles/components/_input.scss +35 -35
  272. package/styles/components/_list.scss +185 -185
  273. package/styles/components/_loader.scss +152 -152
  274. package/styles/components/_login.scss +140 -140
  275. package/styles/components/_mixins.scss +579 -579
  276. package/styles/components/_navbar.scss +765 -765
  277. package/styles/components/_passenger-picker.scss +306 -306
  278. package/styles/components/_phone-input.scss +8 -8
  279. package/styles/components/_placeholders.scss +165 -165
  280. package/styles/components/_pricing-summary.scss +163 -163
  281. package/styles/components/_qsm.scss +17 -17
  282. package/styles/components/_radiobutton.scss +170 -170
  283. package/styles/components/_search.scss +2089 -2089
  284. package/styles/components/_select-wrapper.scss +81 -81
  285. package/styles/components/_slider.scss +128 -128
  286. package/styles/components/_spinner.scss +29 -29
  287. package/styles/components/_step-indicators.scss +187 -187
  288. package/styles/components/_table.scss +81 -81
  289. package/styles/components/_tree.scss +648 -648
  290. package/styles/components/_typeahead.scss +275 -275
  291. package/styles/components/_variables.scss +89 -89
  292. package/styles/content-blocks-variables.scss +507 -507
  293. package/styles/content-blocks.scss +65 -65
  294. package/styles/font.scss +2 -2
  295. package/styles/qsm/_calendar.scss +274 -274
  296. package/styles/qsm/_qsm.scss +1097 -1097
  297. package/styles/search.scss +1200 -1200
  298. package/tsconfig.json +24 -24
  299. package/build/build-cjs/index.js +0 -57386
  300. package/build/build-cjs/src/booking-product/components/age-select.d.ts +0 -8
  301. package/build/build-cjs/src/booking-product/components/amount-input.d.ts +0 -10
  302. package/build/build-cjs/src/booking-product/components/date-range-picker/calendar-day.d.ts +0 -13
  303. package/build/build-cjs/src/booking-product/components/date-range-picker/calendar.d.ts +0 -19
  304. package/build/build-cjs/src/booking-product/components/date-range-picker/index.d.ts +0 -22
  305. package/build/build-cjs/src/booking-product/components/dates.d.ts +0 -14
  306. package/build/build-cjs/src/booking-product/components/footer.d.ts +0 -10
  307. package/build/build-cjs/src/booking-product/components/header.d.ts +0 -11
  308. package/build/build-cjs/src/booking-product/components/list-view.d.ts +0 -8
  309. package/build/build-cjs/src/booking-product/components/product.d.ts +0 -9
  310. package/build/build-cjs/src/booking-product/components/rating.d.ts +0 -6
  311. package/build/build-cjs/src/booking-product/components/rooms.d.ts +0 -10
  312. package/build/build-cjs/src/booking-product/constants.d.ts +0 -1
  313. package/build/build-cjs/src/booking-product/index.d.ts +0 -10
  314. package/build/build-cjs/src/booking-product/settings-context.d.ts +0 -5
  315. package/build/build-cjs/src/booking-product/types.d.ts +0 -27
  316. package/build/build-cjs/src/booking-product/utils/api.d.ts +0 -16
  317. package/build/build-cjs/src/booking-product/utils/price.d.ts +0 -10
  318. package/build/build-cjs/src/booking-wizard/api-settings-slice.d.ts +0 -5
  319. package/build/build-cjs/src/booking-wizard/components/labeled-input.d.ts +0 -18
  320. package/build/build-cjs/src/booking-wizard/components/labeled-select.d.ts +0 -21
  321. package/build/build-cjs/src/booking-wizard/components/message.d.ts +0 -9
  322. package/build/build-cjs/src/booking-wizard/components/multi-range-filter.d.ts +0 -11
  323. package/build/build-cjs/src/booking-wizard/components/phone-input.d.ts +0 -17
  324. package/build/build-cjs/src/booking-wizard/components/print-offer-button.d.ts +0 -17
  325. package/build/build-cjs/src/booking-wizard/components/step-indicator.d.ts +0 -6
  326. package/build/build-cjs/src/booking-wizard/components/step-route.d.ts +0 -8
  327. package/build/build-cjs/src/booking-wizard/features/booking/api.d.ts +0 -30
  328. package/build/build-cjs/src/booking-wizard/features/booking/booking-self-contained.d.ts +0 -8
  329. package/build/build-cjs/src/booking-wizard/features/booking/booking-slice.d.ts +0 -121
  330. package/build/build-cjs/src/booking-wizard/features/booking/booking.d.ts +0 -8
  331. package/build/build-cjs/src/booking-wizard/features/booking/constants.d.ts +0 -15
  332. package/build/build-cjs/src/booking-wizard/features/booking/selectors.d.ts +0 -803
  333. package/build/build-cjs/src/booking-wizard/features/confirmation/confirmation.d.ts +0 -4
  334. package/build/build-cjs/src/booking-wizard/features/error/error.d.ts +0 -4
  335. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-filter.d.ts +0 -9
  336. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-option-flight.d.ts +0 -8
  337. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-option-modal.d.ts +0 -3
  338. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-option.d.ts +0 -10
  339. package/build/build-cjs/src/booking-wizard/features/flight-options/flight-utils.d.ts +0 -13
  340. package/build/build-cjs/src/booking-wizard/features/flight-options/index.d.ts +0 -4
  341. package/build/build-cjs/src/booking-wizard/features/price-details/price-details-api.d.ts +0 -11
  342. package/build/build-cjs/src/booking-wizard/features/price-details/price-details-slice.d.ts +0 -28
  343. package/build/build-cjs/src/booking-wizard/features/price-details/selectors.d.ts +0 -393
  344. package/build/build-cjs/src/booking-wizard/features/price-details/util.d.ts +0 -2
  345. package/build/build-cjs/src/booking-wizard/features/product-options/no-options.d.ts +0 -3
  346. package/build/build-cjs/src/booking-wizard/features/product-options/none-option.d.ts +0 -9
  347. package/build/build-cjs/src/booking-wizard/features/product-options/option-booking-airline-group.d.ts +0 -8
  348. package/build/build-cjs/src/booking-wizard/features/product-options/option-booking-group.d.ts +0 -12
  349. package/build/build-cjs/src/booking-wizard/features/product-options/option-item.d.ts +0 -11
  350. package/build/build-cjs/src/booking-wizard/features/product-options/option-pax-card.d.ts +0 -10
  351. package/build/build-cjs/src/booking-wizard/features/product-options/option-pax-group.d.ts +0 -13
  352. package/build/build-cjs/src/booking-wizard/features/product-options/option-room.d.ts +0 -11
  353. package/build/build-cjs/src/booking-wizard/features/product-options/option-unit-group.d.ts +0 -13
  354. package/build/build-cjs/src/booking-wizard/features/product-options/option-units-card.d.ts +0 -9
  355. package/build/build-cjs/src/booking-wizard/features/product-options/options-form.d.ts +0 -4
  356. package/build/build-cjs/src/booking-wizard/features/room-options/index.d.ts +0 -4
  357. package/build/build-cjs/src/booking-wizard/features/room-options/room-utils.d.ts +0 -22
  358. package/build/build-cjs/src/booking-wizard/features/room-options/room.d.ts +0 -12
  359. package/build/build-cjs/src/booking-wizard/features/room-options/traveler-rooms.d.ts +0 -9
  360. package/build/build-cjs/src/booking-wizard/features/sidebar/index.d.ts +0 -7
  361. package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar-flight.d.ts +0 -9
  362. package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar-util.d.ts +0 -16
  363. package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar.d.ts +0 -0
  364. package/build/build-cjs/src/booking-wizard/features/summary/summary-booking-option-pax.d.ts +0 -7
  365. package/build/build-cjs/src/booking-wizard/features/summary/summary-booking-option-unit.d.ts +0 -7
  366. package/build/build-cjs/src/booking-wizard/features/summary/summary-flight.d.ts +0 -8
  367. package/build/build-cjs/src/booking-wizard/features/summary/summary-per-booking-option-group.d.ts +0 -7
  368. package/build/build-cjs/src/booking-wizard/features/summary/summary-per-pax-option-group.d.ts +0 -7
  369. package/build/build-cjs/src/booking-wizard/features/summary/summary-per-unit-option-group.d.ts +0 -7
  370. package/build/build-cjs/src/booking-wizard/features/summary/summary-slice.d.ts +0 -8
  371. package/build/build-cjs/src/booking-wizard/features/summary/summary.d.ts +0 -4
  372. package/build/build-cjs/src/booking-wizard/features/travelers-form/controls/gender-control.d.ts +0 -5
  373. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +0 -104
  374. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form-util.d.ts +0 -7
  375. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form.d.ts +0 -3
  376. package/build/build-cjs/src/booking-wizard/features/travelers-form/type-ahead-input.d.ts +0 -16
  377. package/build/build-cjs/src/booking-wizard/features/travelers-form/validate-form.d.ts +0 -11
  378. package/build/build-cjs/src/booking-wizard/index.d.ts +0 -12
  379. package/build/build-cjs/src/booking-wizard/settings-context.d.ts +0 -5
  380. package/build/build-cjs/src/booking-wizard/store.d.ts +0 -44
  381. package/build/build-cjs/src/booking-wizard/types.d.ts +0 -301
  382. package/build/build-cjs/src/booking-wizard/use-offer-printer.d.ts +0 -13
  383. package/build/build-cjs/src/content/components/LanguageSwitcher.d.ts +0 -12
  384. package/build/build-cjs/src/content/components/accordion.d.ts +0 -9
  385. package/build/build-cjs/src/content/components/breadcrumb.d.ts +0 -14
  386. package/build/build-cjs/src/content/components/contact.d.ts +0 -3
  387. package/build/build-cjs/src/content/components/faq.d.ts +0 -11
  388. package/build/build-cjs/src/content/components/gallery.d.ts +0 -13
  389. package/build/build-cjs/src/content/components/image-with-text.d.ts +0 -29
  390. package/build/build-cjs/src/content/components/login.d.ts +0 -3
  391. package/build/build-cjs/src/content/components/personal-contact-form.d.ts +0 -3
  392. package/build/build-cjs/src/content/components/slider.d.ts +0 -10
  393. package/build/build-cjs/src/content/error/error.d.ts +0 -6
  394. package/build/build-cjs/src/content/featured-trips/featured-trip-card.d.ts +0 -4
  395. package/build/build-cjs/src/content/featured-trips/index.d.ts +0 -4
  396. package/build/build-cjs/src/content/featured-trips/types.d.ts +0 -12
  397. package/build/build-cjs/src/content/features/content-page/content-page-self-contained.d.ts +0 -6
  398. package/build/build-cjs/src/content/footer/index.d.ts +0 -4
  399. package/build/build-cjs/src/content/footer/types.d.ts +0 -27
  400. package/build/build-cjs/src/content/header/index.d.ts +0 -4
  401. package/build/build-cjs/src/content/header/types.d.ts +0 -25
  402. package/build/build-cjs/src/content/image-card-grid/index.d.ts +0 -4
  403. package/build/build-cjs/src/content/image-card-grid/types.d.ts +0 -12
  404. package/build/build-cjs/src/content/image-with-text-section/card.d.ts +0 -4
  405. package/build/build-cjs/src/content/image-with-text-section/index.d.ts +0 -4
  406. package/build/build-cjs/src/content/image-with-text-section/types.d.ts +0 -19
  407. package/build/build-cjs/src/content/login/confirm-component.d.ts +0 -4
  408. package/build/build-cjs/src/content/login/index.d.ts +0 -4
  409. package/build/build-cjs/src/content/login/login-component.d.ts +0 -4
  410. package/build/build-cjs/src/content/login/login-services.d.ts +0 -11
  411. package/build/build-cjs/src/content/login/reset-password-component.d.ts +0 -4
  412. package/build/build-cjs/src/content/login/types.d.ts +0 -24
  413. package/build/build-cjs/src/content/navbar/index.d.ts +0 -4
  414. package/build/build-cjs/src/content/navbar/placeholderData.d.ts +0 -12
  415. package/build/build-cjs/src/content/navbar/types.d.ts +0 -32
  416. package/build/build-cjs/src/index.d.ts +0 -44
  417. package/build/build-cjs/src/qsm/components/QSMContainer/qsm-container.d.ts +0 -3
  418. package/build/build-cjs/src/qsm/components/date-picker/index.d.ts +0 -3
  419. package/build/build-cjs/src/qsm/components/date-range-picker/calendar-day.d.ts +0 -12
  420. package/build/build-cjs/src/qsm/components/date-range-picker/calendar.d.ts +0 -24
  421. package/build/build-cjs/src/qsm/components/date-range-picker/index.d.ts +0 -10
  422. package/build/build-cjs/src/qsm/components/double-search-input-group/index.d.ts +0 -8
  423. package/build/build-cjs/src/qsm/components/item-picker/index.d.ts +0 -13
  424. package/build/build-cjs/src/qsm/components/mobile-filter-modal/index.d.ts +0 -3
  425. package/build/build-cjs/src/qsm/components/search-input/index.d.ts +0 -15
  426. package/build/build-cjs/src/qsm/components/search-input-group/index.d.ts +0 -13
  427. package/build/build-cjs/src/qsm/components/travel-class-picker/index.d.ts +0 -3
  428. package/build/build-cjs/src/qsm/components/travel-input/index.d.ts +0 -3
  429. package/build/build-cjs/src/qsm/components/travel-input-group/index.d.ts +0 -3
  430. package/build/build-cjs/src/qsm/components/travel-nationality-picker/index.d.ts +0 -3
  431. package/build/build-cjs/src/qsm/components/travel-type-picker/index.d.ts +0 -3
  432. package/build/build-cjs/src/qsm/index.d.ts +0 -7
  433. package/build/build-cjs/src/qsm/qsm-configuration-context.d.ts +0 -4
  434. package/build/build-cjs/src/qsm/store/qsm-slice.d.ts +0 -127
  435. package/build/build-cjs/src/qsm/store/qsm-store.d.ts +0 -23
  436. package/build/build-cjs/src/qsm/types.d.ts +0 -82
  437. package/build/build-cjs/src/search-results/components/book-packaging-entry/index.d.ts +0 -9
  438. package/build/build-cjs/src/search-results/components/book-packaging-entry/wl-sidebar.d.ts +0 -9
  439. package/build/build-cjs/src/search-results/components/excursions/day-by-day-excursions.d.ts +0 -4
  440. package/build/build-cjs/src/search-results/components/excursions/excursion-details.d.ts +0 -3
  441. package/build/build-cjs/src/search-results/components/excursions/excursion-results.d.ts +0 -8
  442. package/build/build-cjs/src/search-results/components/filters/filters.d.ts +0 -13
  443. package/build/build-cjs/src/search-results/components/filters/flight-filters.d.ts +0 -8
  444. package/build/build-cjs/src/search-results/components/flight/flight-banner.d.ts +0 -8
  445. package/build/build-cjs/src/search-results/components/flight/flight-card.d.ts +0 -7
  446. package/build/build-cjs/src/search-results/components/flight/flight-leg.d.ts +0 -7
  447. package/build/build-cjs/src/search-results/components/flight/flight-path.d.ts +0 -6
  448. package/build/build-cjs/src/search-results/components/flight/flight-results.d.ts +0 -8
  449. package/build/build-cjs/src/search-results/components/flight/flight-search-context/index.d.ts +0 -39
  450. package/build/build-cjs/src/search-results/components/flight/flight-selection/independent-flight-option.d.ts +0 -14
  451. package/build/build-cjs/src/search-results/components/flight/flight-selection/independent-flight-selection.d.ts +0 -7
  452. package/build/build-cjs/src/search-results/components/flight/flight-selection/index.d.ts +0 -8
  453. package/build/build-cjs/src/search-results/components/flight/flight-selection/paired-flight-option.d.ts +0 -7
  454. package/build/build-cjs/src/search-results/components/flight/flight-selection/paired-flight-selection.d.ts +0 -7
  455. package/build/build-cjs/src/search-results/components/group-tour/group-tour-card.d.ts +0 -9
  456. package/build/build-cjs/src/search-results/components/group-tour/group-tour-results.d.ts +0 -6
  457. package/build/build-cjs/src/search-results/components/hotel/hotel-accommodation-results.d.ts +0 -7
  458. package/build/build-cjs/src/search-results/components/hotel/hotel-card.d.ts +0 -8
  459. package/build/build-cjs/src/search-results/components/item-picker/index.d.ts +0 -15
  460. package/build/build-cjs/src/search-results/components/itinerary/full-itinerary.d.ts +0 -6
  461. package/build/build-cjs/src/search-results/components/itinerary/index.d.ts +0 -10
  462. package/build/build-cjs/src/search-results/components/multi-range-filter.d.ts +0 -11
  463. package/build/build-cjs/src/search-results/components/round-trip/round-trip-results.d.ts +0 -4
  464. package/build/build-cjs/src/search-results/components/search-results-container/flight-search-results.d.ts +0 -6
  465. package/build/build-cjs/src/search-results/components/search-results-container/search-results-container.d.ts +0 -6
  466. package/build/build-cjs/src/search-results/components/spinner/spinner.d.ts +0 -6
  467. package/build/build-cjs/src/search-results/components/tab-views/index.d.ts +0 -4
  468. package/build/build-cjs/src/search-results/features/flights/flight-search-results-self-contained.d.ts +0 -4
  469. package/build/build-cjs/src/search-results/features/hotels/hotel-flight-search-results-self-contained.d.ts +0 -4
  470. package/build/build-cjs/src/search-results/features/hotels/hotel-search-results-self-contained.d.ts +0 -4
  471. package/build/build-cjs/src/search-results/features/roundtrips/roundtrip-search-results-self-contained.d.ts +0 -4
  472. package/build/build-cjs/src/search-results/index.d.ts +0 -8
  473. package/build/build-cjs/src/search-results/search-results-configuration-context.d.ts +0 -4
  474. package/build/build-cjs/src/search-results/store/search-results-selectors.d.ts +0 -546
  475. package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +0 -138
  476. package/build/build-cjs/src/search-results/store/search-results-store.d.ts +0 -23
  477. package/build/build-cjs/src/search-results/types.d.ts +0 -211
  478. package/build/build-cjs/src/search-results/utils/flight-utils.d.ts +0 -16
  479. package/build/build-cjs/src/search-results/utils/packaging-utils.d.ts +0 -7
  480. package/build/build-cjs/src/search-results/utils/query-utils.d.ts +0 -12
  481. package/build/build-cjs/src/search-results/utils/search-results-utils.d.ts +0 -16
  482. package/build/build-cjs/src/shared/booking/booking-panel.d.ts +0 -13
  483. package/build/build-cjs/src/shared/booking/product-card.d.ts +0 -8
  484. package/build/build-cjs/src/shared/booking/shared-confirmation.d.ts +0 -25
  485. package/build/build-cjs/src/shared/booking/shared-sidebar.d.ts +0 -34
  486. package/build/build-cjs/src/shared/booking/step-indicators.d.ts +0 -7
  487. package/build/build-cjs/src/shared/booking/summary.d.ts +0 -44
  488. package/build/build-cjs/src/shared/booking/travelers-form.d.ts +0 -93
  489. package/build/build-cjs/src/shared/components/flyin/accommodation-flyin.d.ts +0 -7
  490. package/build/build-cjs/src/shared/components/flyin/flights-flyin.d.ts +0 -7
  491. package/build/build-cjs/src/shared/components/flyin/flyin.d.ts +0 -20
  492. package/build/build-cjs/src/shared/components/flyin/group-tour-flyin.d.ts +0 -8
  493. package/build/build-cjs/src/shared/components/flyin/packaging-flights-flyin.d.ts +0 -9
  494. package/build/build-cjs/src/shared/components/icon.d.ts +0 -11
  495. package/build/build-cjs/src/shared/components/loader.d.ts +0 -6
  496. package/build/build-cjs/src/shared/types.d.ts +0 -16
  497. package/build/build-cjs/src/shared/utils/booking-summary.d.ts +0 -2
  498. package/build/build-cjs/src/shared/utils/class-util.d.ts +0 -1
  499. package/build/build-cjs/src/shared/utils/localization-util.d.ts +0 -440
  500. package/build/build-cjs/src/shared/utils/query-string-util.d.ts +0 -8
  501. package/build/build-cjs/src/shared/utils/tide-api-utils.d.ts +0 -10
  502. package/build/build-cjs/src/shared/utils/use-media-query-util.d.ts +0 -2
  503. package/build/build-esm/index.js +0 -57136
  504. package/build/build-esm/src/booking-product/components/age-select.d.ts +0 -8
  505. package/build/build-esm/src/booking-product/components/amount-input.d.ts +0 -10
  506. package/build/build-esm/src/booking-product/components/date-range-picker/calendar-day.d.ts +0 -13
  507. package/build/build-esm/src/booking-product/components/date-range-picker/calendar.d.ts +0 -19
  508. package/build/build-esm/src/booking-product/components/date-range-picker/index.d.ts +0 -22
  509. package/build/build-esm/src/booking-product/components/dates.d.ts +0 -14
  510. package/build/build-esm/src/booking-product/components/footer.d.ts +0 -10
  511. package/build/build-esm/src/booking-product/components/header.d.ts +0 -11
  512. package/build/build-esm/src/booking-product/components/list-view.d.ts +0 -8
  513. package/build/build-esm/src/booking-product/components/product.d.ts +0 -9
  514. package/build/build-esm/src/booking-product/components/rating.d.ts +0 -6
  515. package/build/build-esm/src/booking-product/components/rooms.d.ts +0 -10
  516. package/build/build-esm/src/booking-product/constants.d.ts +0 -1
  517. package/build/build-esm/src/booking-product/index.d.ts +0 -10
  518. package/build/build-esm/src/booking-product/settings-context.d.ts +0 -5
  519. package/build/build-esm/src/booking-product/types.d.ts +0 -27
  520. package/build/build-esm/src/booking-product/utils/api.d.ts +0 -16
  521. package/build/build-esm/src/booking-product/utils/price.d.ts +0 -10
  522. package/build/build-esm/src/booking-wizard/api-settings-slice.d.ts +0 -5
  523. package/build/build-esm/src/booking-wizard/components/labeled-input.d.ts +0 -18
  524. package/build/build-esm/src/booking-wizard/components/labeled-select.d.ts +0 -21
  525. package/build/build-esm/src/booking-wizard/components/message.d.ts +0 -9
  526. package/build/build-esm/src/booking-wizard/components/multi-range-filter.d.ts +0 -11
  527. package/build/build-esm/src/booking-wizard/components/phone-input.d.ts +0 -17
  528. package/build/build-esm/src/booking-wizard/components/print-offer-button.d.ts +0 -17
  529. package/build/build-esm/src/booking-wizard/components/step-indicator.d.ts +0 -6
  530. package/build/build-esm/src/booking-wizard/components/step-route.d.ts +0 -8
  531. package/build/build-esm/src/booking-wizard/features/booking/api.d.ts +0 -30
  532. package/build/build-esm/src/booking-wizard/features/booking/booking-self-contained.d.ts +0 -8
  533. package/build/build-esm/src/booking-wizard/features/booking/booking-slice.d.ts +0 -121
  534. package/build/build-esm/src/booking-wizard/features/booking/booking.d.ts +0 -8
  535. package/build/build-esm/src/booking-wizard/features/booking/constants.d.ts +0 -15
  536. package/build/build-esm/src/booking-wizard/features/booking/selectors.d.ts +0 -803
  537. package/build/build-esm/src/booking-wizard/features/confirmation/confirmation.d.ts +0 -4
  538. package/build/build-esm/src/booking-wizard/features/error/error.d.ts +0 -4
  539. package/build/build-esm/src/booking-wizard/features/flight-options/flight-filter.d.ts +0 -9
  540. package/build/build-esm/src/booking-wizard/features/flight-options/flight-option-flight.d.ts +0 -8
  541. package/build/build-esm/src/booking-wizard/features/flight-options/flight-option-modal.d.ts +0 -3
  542. package/build/build-esm/src/booking-wizard/features/flight-options/flight-option.d.ts +0 -10
  543. package/build/build-esm/src/booking-wizard/features/flight-options/flight-utils.d.ts +0 -13
  544. package/build/build-esm/src/booking-wizard/features/flight-options/index.d.ts +0 -4
  545. package/build/build-esm/src/booking-wizard/features/price-details/price-details-api.d.ts +0 -11
  546. package/build/build-esm/src/booking-wizard/features/price-details/price-details-slice.d.ts +0 -28
  547. package/build/build-esm/src/booking-wizard/features/price-details/selectors.d.ts +0 -393
  548. package/build/build-esm/src/booking-wizard/features/price-details/util.d.ts +0 -2
  549. package/build/build-esm/src/booking-wizard/features/product-options/no-options.d.ts +0 -3
  550. package/build/build-esm/src/booking-wizard/features/product-options/none-option.d.ts +0 -9
  551. package/build/build-esm/src/booking-wizard/features/product-options/option-booking-airline-group.d.ts +0 -8
  552. package/build/build-esm/src/booking-wizard/features/product-options/option-booking-group.d.ts +0 -12
  553. package/build/build-esm/src/booking-wizard/features/product-options/option-item.d.ts +0 -11
  554. package/build/build-esm/src/booking-wizard/features/product-options/option-pax-card.d.ts +0 -10
  555. package/build/build-esm/src/booking-wizard/features/product-options/option-pax-group.d.ts +0 -13
  556. package/build/build-esm/src/booking-wizard/features/product-options/option-room.d.ts +0 -11
  557. package/build/build-esm/src/booking-wizard/features/product-options/option-unit-group.d.ts +0 -13
  558. package/build/build-esm/src/booking-wizard/features/product-options/option-units-card.d.ts +0 -9
  559. package/build/build-esm/src/booking-wizard/features/product-options/options-form.d.ts +0 -4
  560. package/build/build-esm/src/booking-wizard/features/room-options/index.d.ts +0 -4
  561. package/build/build-esm/src/booking-wizard/features/room-options/room-utils.d.ts +0 -22
  562. package/build/build-esm/src/booking-wizard/features/room-options/room.d.ts +0 -12
  563. package/build/build-esm/src/booking-wizard/features/room-options/traveler-rooms.d.ts +0 -9
  564. package/build/build-esm/src/booking-wizard/features/sidebar/index.d.ts +0 -7
  565. package/build/build-esm/src/booking-wizard/features/sidebar/sidebar-flight.d.ts +0 -9
  566. package/build/build-esm/src/booking-wizard/features/sidebar/sidebar-util.d.ts +0 -16
  567. package/build/build-esm/src/booking-wizard/features/sidebar/sidebar.d.ts +0 -0
  568. package/build/build-esm/src/booking-wizard/features/summary/summary-booking-option-pax.d.ts +0 -7
  569. package/build/build-esm/src/booking-wizard/features/summary/summary-booking-option-unit.d.ts +0 -7
  570. package/build/build-esm/src/booking-wizard/features/summary/summary-flight.d.ts +0 -8
  571. package/build/build-esm/src/booking-wizard/features/summary/summary-per-booking-option-group.d.ts +0 -7
  572. package/build/build-esm/src/booking-wizard/features/summary/summary-per-pax-option-group.d.ts +0 -7
  573. package/build/build-esm/src/booking-wizard/features/summary/summary-per-unit-option-group.d.ts +0 -7
  574. package/build/build-esm/src/booking-wizard/features/summary/summary-slice.d.ts +0 -8
  575. package/build/build-esm/src/booking-wizard/features/summary/summary.d.ts +0 -4
  576. package/build/build-esm/src/booking-wizard/features/travelers-form/controls/gender-control.d.ts +0 -5
  577. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +0 -104
  578. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form-util.d.ts +0 -7
  579. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form.d.ts +0 -3
  580. package/build/build-esm/src/booking-wizard/features/travelers-form/type-ahead-input.d.ts +0 -16
  581. package/build/build-esm/src/booking-wizard/features/travelers-form/validate-form.d.ts +0 -11
  582. package/build/build-esm/src/booking-wizard/index.d.ts +0 -12
  583. package/build/build-esm/src/booking-wizard/settings-context.d.ts +0 -5
  584. package/build/build-esm/src/booking-wizard/store.d.ts +0 -44
  585. package/build/build-esm/src/booking-wizard/types.d.ts +0 -301
  586. package/build/build-esm/src/booking-wizard/use-offer-printer.d.ts +0 -13
  587. package/build/build-esm/src/content/components/LanguageSwitcher.d.ts +0 -12
  588. package/build/build-esm/src/content/components/accordion.d.ts +0 -9
  589. package/build/build-esm/src/content/components/breadcrumb.d.ts +0 -14
  590. package/build/build-esm/src/content/components/contact.d.ts +0 -3
  591. package/build/build-esm/src/content/components/faq.d.ts +0 -11
  592. package/build/build-esm/src/content/components/gallery.d.ts +0 -13
  593. package/build/build-esm/src/content/components/image-with-text.d.ts +0 -29
  594. package/build/build-esm/src/content/components/login.d.ts +0 -3
  595. package/build/build-esm/src/content/components/personal-contact-form.d.ts +0 -3
  596. package/build/build-esm/src/content/components/slider.d.ts +0 -10
  597. package/build/build-esm/src/content/error/error.d.ts +0 -6
  598. package/build/build-esm/src/content/featured-trips/featured-trip-card.d.ts +0 -4
  599. package/build/build-esm/src/content/featured-trips/index.d.ts +0 -4
  600. package/build/build-esm/src/content/featured-trips/types.d.ts +0 -12
  601. package/build/build-esm/src/content/features/content-page/content-page-self-contained.d.ts +0 -6
  602. package/build/build-esm/src/content/footer/index.d.ts +0 -4
  603. package/build/build-esm/src/content/footer/types.d.ts +0 -27
  604. package/build/build-esm/src/content/header/index.d.ts +0 -4
  605. package/build/build-esm/src/content/header/types.d.ts +0 -25
  606. package/build/build-esm/src/content/image-card-grid/index.d.ts +0 -4
  607. package/build/build-esm/src/content/image-card-grid/types.d.ts +0 -12
  608. package/build/build-esm/src/content/image-with-text-section/card.d.ts +0 -4
  609. package/build/build-esm/src/content/image-with-text-section/index.d.ts +0 -4
  610. package/build/build-esm/src/content/image-with-text-section/types.d.ts +0 -19
  611. package/build/build-esm/src/content/login/confirm-component.d.ts +0 -4
  612. package/build/build-esm/src/content/login/index.d.ts +0 -4
  613. package/build/build-esm/src/content/login/login-component.d.ts +0 -4
  614. package/build/build-esm/src/content/login/login-services.d.ts +0 -11
  615. package/build/build-esm/src/content/login/reset-password-component.d.ts +0 -4
  616. package/build/build-esm/src/content/login/types.d.ts +0 -24
  617. package/build/build-esm/src/content/navbar/index.d.ts +0 -4
  618. package/build/build-esm/src/content/navbar/placeholderData.d.ts +0 -12
  619. package/build/build-esm/src/content/navbar/types.d.ts +0 -32
  620. package/build/build-esm/src/index.d.ts +0 -44
  621. package/build/build-esm/src/qsm/components/QSMContainer/qsm-container.d.ts +0 -3
  622. package/build/build-esm/src/qsm/components/date-picker/index.d.ts +0 -3
  623. package/build/build-esm/src/qsm/components/date-range-picker/calendar-day.d.ts +0 -12
  624. package/build/build-esm/src/qsm/components/date-range-picker/calendar.d.ts +0 -24
  625. package/build/build-esm/src/qsm/components/date-range-picker/index.d.ts +0 -10
  626. package/build/build-esm/src/qsm/components/double-search-input-group/index.d.ts +0 -8
  627. package/build/build-esm/src/qsm/components/item-picker/index.d.ts +0 -13
  628. package/build/build-esm/src/qsm/components/mobile-filter-modal/index.d.ts +0 -3
  629. package/build/build-esm/src/qsm/components/search-input/index.d.ts +0 -15
  630. package/build/build-esm/src/qsm/components/search-input-group/index.d.ts +0 -13
  631. package/build/build-esm/src/qsm/components/travel-class-picker/index.d.ts +0 -3
  632. package/build/build-esm/src/qsm/components/travel-input/index.d.ts +0 -3
  633. package/build/build-esm/src/qsm/components/travel-input-group/index.d.ts +0 -3
  634. package/build/build-esm/src/qsm/components/travel-nationality-picker/index.d.ts +0 -3
  635. package/build/build-esm/src/qsm/components/travel-type-picker/index.d.ts +0 -3
  636. package/build/build-esm/src/qsm/index.d.ts +0 -7
  637. package/build/build-esm/src/qsm/qsm-configuration-context.d.ts +0 -4
  638. package/build/build-esm/src/qsm/store/qsm-slice.d.ts +0 -127
  639. package/build/build-esm/src/qsm/store/qsm-store.d.ts +0 -23
  640. package/build/build-esm/src/qsm/types.d.ts +0 -82
  641. package/build/build-esm/src/search-results/components/book-packaging-entry/index.d.ts +0 -9
  642. package/build/build-esm/src/search-results/components/book-packaging-entry/wl-sidebar.d.ts +0 -9
  643. package/build/build-esm/src/search-results/components/excursions/day-by-day-excursions.d.ts +0 -4
  644. package/build/build-esm/src/search-results/components/excursions/excursion-details.d.ts +0 -3
  645. package/build/build-esm/src/search-results/components/excursions/excursion-results.d.ts +0 -8
  646. package/build/build-esm/src/search-results/components/filters/filters.d.ts +0 -13
  647. package/build/build-esm/src/search-results/components/filters/flight-filters.d.ts +0 -8
  648. package/build/build-esm/src/search-results/components/flight/flight-banner.d.ts +0 -8
  649. package/build/build-esm/src/search-results/components/flight/flight-card.d.ts +0 -7
  650. package/build/build-esm/src/search-results/components/flight/flight-leg.d.ts +0 -7
  651. package/build/build-esm/src/search-results/components/flight/flight-path.d.ts +0 -6
  652. package/build/build-esm/src/search-results/components/flight/flight-results.d.ts +0 -8
  653. package/build/build-esm/src/search-results/components/flight/flight-search-context/index.d.ts +0 -39
  654. package/build/build-esm/src/search-results/components/flight/flight-selection/independent-flight-option.d.ts +0 -14
  655. package/build/build-esm/src/search-results/components/flight/flight-selection/independent-flight-selection.d.ts +0 -7
  656. package/build/build-esm/src/search-results/components/flight/flight-selection/index.d.ts +0 -8
  657. package/build/build-esm/src/search-results/components/flight/flight-selection/paired-flight-option.d.ts +0 -7
  658. package/build/build-esm/src/search-results/components/flight/flight-selection/paired-flight-selection.d.ts +0 -7
  659. package/build/build-esm/src/search-results/components/group-tour/group-tour-card.d.ts +0 -9
  660. package/build/build-esm/src/search-results/components/group-tour/group-tour-results.d.ts +0 -6
  661. package/build/build-esm/src/search-results/components/hotel/hotel-accommodation-results.d.ts +0 -7
  662. package/build/build-esm/src/search-results/components/hotel/hotel-card.d.ts +0 -8
  663. package/build/build-esm/src/search-results/components/item-picker/index.d.ts +0 -15
  664. package/build/build-esm/src/search-results/components/itinerary/full-itinerary.d.ts +0 -6
  665. package/build/build-esm/src/search-results/components/itinerary/index.d.ts +0 -10
  666. package/build/build-esm/src/search-results/components/multi-range-filter.d.ts +0 -11
  667. package/build/build-esm/src/search-results/components/round-trip/round-trip-results.d.ts +0 -4
  668. package/build/build-esm/src/search-results/components/search-results-container/flight-search-results.d.ts +0 -6
  669. package/build/build-esm/src/search-results/components/search-results-container/search-results-container.d.ts +0 -6
  670. package/build/build-esm/src/search-results/components/spinner/spinner.d.ts +0 -6
  671. package/build/build-esm/src/search-results/components/tab-views/index.d.ts +0 -4
  672. package/build/build-esm/src/search-results/features/flights/flight-search-results-self-contained.d.ts +0 -4
  673. package/build/build-esm/src/search-results/features/hotels/hotel-flight-search-results-self-contained.d.ts +0 -4
  674. package/build/build-esm/src/search-results/features/hotels/hotel-search-results-self-contained.d.ts +0 -4
  675. package/build/build-esm/src/search-results/features/roundtrips/roundtrip-search-results-self-contained.d.ts +0 -4
  676. package/build/build-esm/src/search-results/index.d.ts +0 -8
  677. package/build/build-esm/src/search-results/search-results-configuration-context.d.ts +0 -4
  678. package/build/build-esm/src/search-results/store/search-results-selectors.d.ts +0 -546
  679. package/build/build-esm/src/search-results/store/search-results-slice.d.ts +0 -138
  680. package/build/build-esm/src/search-results/store/search-results-store.d.ts +0 -23
  681. package/build/build-esm/src/search-results/types.d.ts +0 -211
  682. package/build/build-esm/src/search-results/utils/flight-utils.d.ts +0 -16
  683. package/build/build-esm/src/search-results/utils/packaging-utils.d.ts +0 -7
  684. package/build/build-esm/src/search-results/utils/query-utils.d.ts +0 -12
  685. package/build/build-esm/src/search-results/utils/search-results-utils.d.ts +0 -16
  686. package/build/build-esm/src/shared/booking/booking-panel.d.ts +0 -13
  687. package/build/build-esm/src/shared/booking/product-card.d.ts +0 -8
  688. package/build/build-esm/src/shared/booking/shared-confirmation.d.ts +0 -25
  689. package/build/build-esm/src/shared/booking/shared-sidebar.d.ts +0 -34
  690. package/build/build-esm/src/shared/booking/step-indicators.d.ts +0 -7
  691. package/build/build-esm/src/shared/booking/summary.d.ts +0 -44
  692. package/build/build-esm/src/shared/booking/travelers-form.d.ts +0 -93
  693. package/build/build-esm/src/shared/components/flyin/accommodation-flyin.d.ts +0 -7
  694. package/build/build-esm/src/shared/components/flyin/flights-flyin.d.ts +0 -7
  695. package/build/build-esm/src/shared/components/flyin/flyin.d.ts +0 -20
  696. package/build/build-esm/src/shared/components/flyin/group-tour-flyin.d.ts +0 -8
  697. package/build/build-esm/src/shared/components/flyin/packaging-flights-flyin.d.ts +0 -9
  698. package/build/build-esm/src/shared/components/icon.d.ts +0 -11
  699. package/build/build-esm/src/shared/components/loader.d.ts +0 -6
  700. package/build/build-esm/src/shared/types.d.ts +0 -16
  701. package/build/build-esm/src/shared/utils/booking-summary.d.ts +0 -2
  702. package/build/build-esm/src/shared/utils/class-util.d.ts +0 -1
  703. package/build/build-esm/src/shared/utils/localization-util.d.ts +0 -440
  704. package/build/build-esm/src/shared/utils/query-string-util.d.ts +0 -8
  705. package/build/build-esm/src/shared/utils/tide-api-utils.d.ts +0 -10
  706. package/build/build-esm/src/shared/utils/use-media-query-util.d.ts +0 -2
@@ -1,809 +1,809 @@
1
- import React, { useMemo, useState } from 'react';
2
- import Icon from '../../shared/components/icon';
3
-
4
- type ContactValues = {
5
- firstName: string;
6
- lastName: string;
7
- dateOfBirth: string;
8
- nationality: string;
9
- email: string;
10
- phone: string;
11
- message: string;
12
- street: string;
13
- houseNumber: string;
14
- box: string;
15
- postalCode: string;
16
- city: string;
17
- country: string;
18
- // traveler 1
19
- bookingType1: 'leisure' | 'business' | '';
20
- gender1: 'female' | 'male' | 'other' | '';
21
-
22
- // traveler 2
23
- bookingType2: 'leisure' | 'business' | '';
24
- gender2: 'female' | 'male' | 'other' | '';
25
- };
26
-
27
- type ContactErrors = Partial<Record<keyof ContactValues, string>>;
28
- // const [touched, setTouched] = useState<Partial<Record<keyof ContactValues, boolean>>>({});
29
-
30
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
31
- const phoneRegex = /^[+()\-.\s0-9]{8,20}$/;
32
-
33
- // Small helper: checks YYYY-MM-DD parses to a real date
34
- const isValidISODate = (value: string) => {
35
- if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return false;
36
- const d = new Date(value);
37
- return !Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) === value;
38
- };
39
-
40
- // You can expand this list later (or load from API)
41
- const nationalityOptions = [
42
- { value: '', label: 'Selecteer nationaliteit' },
43
- { value: 'BE', label: 'Belgisch' },
44
- { value: 'NL', label: 'Nederlands' },
45
- { value: 'FR', label: 'Frans' },
46
- { value: 'DE', label: 'Duits' },
47
- { value: 'UK', label: 'Brits' },
48
- { value: 'US', label: 'Amerikaans' }
49
- ];
50
-
51
- const countryOptions = [
52
- { value: '', label: 'Selecteer land' },
53
- { value: 'BE', label: 'België' },
54
- { value: 'NL', label: 'Nederland' },
55
- { value: 'FR', label: 'Frankrijk' },
56
- { value: 'DE', label: 'Duitsland' },
57
- { value: 'LU', label: 'Luxemburg' },
58
- { value: 'UK', label: 'Verenigd Koninkrijk' }
59
- ];
60
-
61
- const PersonalContactForm: React.FC = () => {
62
- const [values, setValues] = useState<ContactValues>({
63
- firstName: '',
64
- lastName: '',
65
- dateOfBirth: '',
66
- nationality: '',
67
- email: '',
68
- phone: '',
69
- message: '',
70
- street: '',
71
- houseNumber: '',
72
- box: '',
73
- postalCode: '',
74
- city: '',
75
- country: '',
76
- bookingType1: '',
77
- gender1: '',
78
- bookingType2: '',
79
- gender2: ''
80
- });
81
-
82
- const [touched, setTouched] = useState<Partial<Record<keyof ContactValues, boolean>>>({});
83
- const [errors, setErrors] = useState<ContactErrors>({});
84
- const [submitted, setSubmitted] = useState(false);
85
- const [isNationalityOpen, setIsNationalityOpen] = useState(false);
86
- const [isCountryOpen, setIsCountryOpen] = useState(false);
87
-
88
- const postalCodeRegex = /^[0-9A-Za-z\s-]{3,10}$/;
89
-
90
- const validate = (v: ContactValues): ContactErrors => {
91
- const e: ContactErrors = {};
92
-
93
- if (!v.firstName.trim()) e.firstName = 'Voornaam is verplicht.';
94
- if (!v.lastName.trim()) e.lastName = 'Achternaam is verplicht.';
95
-
96
- if (!v.dateOfBirth.trim()) e.dateOfBirth = 'Geboortedatum is verplicht.';
97
- else if (!isValidISODate(v.dateOfBirth.trim())) e.dateOfBirth = 'Vul een geldige geboortedatum in.';
98
-
99
- if (!v.nationality.trim()) e.nationality = 'Nationaliteit is verplicht.';
100
-
101
- if (!v.email.trim()) e.email = 'Email is verplicht.';
102
- else if (!emailRegex.test(v.email.trim())) e.email = 'Vul een geldig e-mailadres in.';
103
-
104
- if (v.phone.trim() && !phoneRegex.test(v.phone.trim())) {
105
- e.phone = 'Vul een geldig telefoonnummer in.';
106
- }
107
-
108
- if (!v.message.trim()) e.message = 'Bericht is verplicht.';
109
- else if (v.message.trim().length < 10) e.message = 'Bericht moet minstens 10 tekens zijn.';
110
-
111
- if (!v.street.trim()) e.street = 'Straat is verplicht.';
112
- if (!v.houseNumber.trim()) e.houseNumber = 'Nummer is verplicht.';
113
-
114
- if (!v.postalCode.trim()) e.postalCode = 'Postcode is verplicht.';
115
- else if (!postalCodeRegex.test(v.postalCode.trim())) e.postalCode = 'Vul een geldige postcode in.';
116
-
117
- if (!v.city.trim()) e.city = 'Woonplaats is verplicht.';
118
- if (!v.country.trim()) e.country = 'Land is verplicht.';
119
-
120
- if (!v.gender1) e.gender1 = 'Geslacht is verplicht.';
121
- if (!v.gender2) e.gender2 = 'Geslacht is verplicht.';
122
-
123
- if (!v.bookingType1) e.bookingType1 = 'Type boeking is verplicht.';
124
- if (!v.bookingType2) e.bookingType2 = 'Type boeking is verplicht.';
125
-
126
- return e;
127
- };
128
-
129
- const currentErrors = useMemo(() => validate(values), [values]);
130
-
131
- const setField = <K extends keyof ContactValues>(key: K, val: ContactValues[K]) => {
132
- setValues((p) => ({ ...p, [key]: val }));
133
- if (submitted || touched[key]) {
134
- setErrors(validate({ ...values, [key]: val } as ContactValues));
135
- }
136
- };
137
-
138
- const onBlur = (key: keyof ContactValues) => {
139
- setTouched((p) => ({ ...p, [key]: true }));
140
- setErrors(validate(values));
141
- };
142
-
143
- const onSubmit = (e: React.FormEvent) => {
144
- e.preventDefault();
145
- setSubmitted(true);
146
-
147
- const eMap = validate(values);
148
- setErrors(eMap);
149
-
150
- if (Object.keys(eMap).length > 0) return;
151
-
152
- console.log('Contact form submit:', values);
153
-
154
- setValues({
155
- firstName: '',
156
- lastName: '',
157
- dateOfBirth: '',
158
- nationality: '',
159
- email: '',
160
- phone: '',
161
- message: '',
162
- street: '',
163
- houseNumber: '',
164
- box: '',
165
- postalCode: '',
166
- city: '',
167
- country: '',
168
- bookingType1: '',
169
- gender1: '',
170
- bookingType2: '',
171
- gender2: ''
172
- });
173
- setTouched({});
174
- setErrors({});
175
- setSubmitted(false);
176
- };
177
-
178
- const showError = (key: keyof ContactValues) => {
179
- const shouldShow = submitted || touched[key];
180
- return shouldShow ? errors[key] : undefined;
181
- };
182
-
183
- return (
184
- <div className="content content--background">
185
- <div className="content__container content__container--medium">
186
- <div className="content__title__row">
187
- <h2 className="content__title">Persoonlijke informatie</h2>
188
- </div>
189
-
190
- <form className="contact" noValidate onSubmit={onSubmit}>
191
- <div className="contact__card contact__card--headbooker">
192
- <div className="contact__title">
193
- <Icon name="ui-info-circle" width={24} height={24} />
194
- <h4>Gaat de hoofdboeker mee op reis?</h4>
195
- </div>
196
-
197
- <div className="contact__form">
198
- <div className="radiobutton-group">
199
- <div className="radiobutton">
200
- <label className="radiobutton__label">
201
- <input type="radio" name="headBooker" value="yes" className="radiobutton__input" defaultChecked={true} />
202
- <span>Ja</span>
203
- </label>
204
- </div>
205
-
206
- <div className="radiobutton">
207
- <label className="radiobutton__label">
208
- <input type="radio" name="headBooker" value="no" className="radiobutton__input" />
209
- <span>Nee</span>
210
- </label>
211
- </div>
212
- </div>
213
- </div>
214
- </div>
215
- <div className="contact__card">
216
- <div className="contact__title">
217
- <Icon name="ui-user" width={24} height={24} />
218
- <h4>Reiziger 1</h4>
219
- <span>volwassenen, hoofdboeker</span>
220
- </div>
221
-
222
- <div
223
- className="contact__radio"
224
- role="group"
225
- aria-labelledby="bookingType-label"
226
- aria-invalid={!!showError('bookingType1')}
227
- aria-describedby="bookingType-error">
228
- <span id="bookingType-label">Type boeking{/** add * if required */}</span>
229
-
230
- <div className="radiobutton-group">
231
- <div className="radiobutton">
232
- <label className="radiobutton__label">
233
- <input
234
- type="radio"
235
- name="bookingType1"
236
- value="leisure"
237
- className="radiobutton__input"
238
- checked={values.bookingType1 === 'leisure'}
239
- onChange={() => setField('bookingType1', 'leisure')}
240
- onBlur={() => onBlur('bookingType1')}
241
- />
242
- <span>Plezier</span>
243
- </label>
244
- </div>
245
-
246
- <div className="radiobutton">
247
- <label className="radiobutton__label">
248
- <input
249
- type="radio"
250
- name="bookingType1"
251
- value="business"
252
- className="radiobutton__input"
253
- checked={values.bookingType1 === 'business'}
254
- onChange={() => setField('bookingType1', 'business')}
255
- onBlur={() => onBlur('bookingType1')}
256
- />
257
- <span>Zakelijk</span>
258
- </label>
259
- </div>
260
- </div>
261
-
262
- {showError('bookingType1') && (
263
- <span className="contact__radio--error" id="bookingType-error">
264
- {showError('bookingType1')}
265
- </span>
266
- )}
267
- </div>
268
-
269
- <div className="contact__radio" role="group" aria-labelledby="gender-label" aria-invalid={!!showError('gender1')} aria-describedby="gender-error">
270
- <span id="gender-label">Geslacht*</span>
271
-
272
- <div className="radiobutton-group">
273
- <div className="radiobutton">
274
- <label className="radiobutton__label">
275
- <input
276
- type="radio"
277
- name="gender1"
278
- value="female"
279
- className="radiobutton__input"
280
- checked={values.gender1 === 'female'}
281
- onChange={() => setField('gender1', 'female')}
282
- onBlur={() => onBlur('gender1')}
283
- />
284
- <span>Vrouw</span>
285
- </label>
286
- </div>
287
-
288
- <div className="radiobutton">
289
- <label className="radiobutton__label">
290
- <input
291
- type="radio"
292
- name="gender1"
293
- value="male"
294
- className="radiobutton__input"
295
- checked={values.gender1 === 'male'}
296
- onChange={() => setField('gender1', 'male')}
297
- onBlur={() => onBlur('gender1')}
298
- />
299
- <span>Man</span>
300
- </label>
301
- </div>
302
-
303
- <div className="radiobutton">
304
- <label className="radiobutton__label">
305
- <input
306
- type="radio"
307
- name="gender1"
308
- value="other"
309
- className="radiobutton__input"
310
- checked={values.gender1 === 'other'}
311
- onChange={() => setField('gender1', 'other')}
312
- onBlur={() => onBlur('gender1')}
313
- />
314
- <span>Anders</span>
315
- </label>
316
- </div>
317
- </div>
318
-
319
- {showError('gender1') && (
320
- <span className="contact__radio--error" id="gender-error">
321
- {showError('gender1')}
322
- </span>
323
- )}
324
- </div>
325
-
326
- <div className="contact__form">
327
- <label className="contact__form__group contact__form__group--3">
328
- <span className="contact__form__label">Voornaam*</span>
329
- <input
330
- type="text"
331
- className="contact__input"
332
- placeholder="Enter your name"
333
- aria-label="Enter your name"
334
- value={values.firstName}
335
- onChange={(e) => setField('firstName', e.target.value)}
336
- onBlur={() => onBlur('firstName')}
337
- aria-invalid={!!showError('firstName')}
338
- aria-describedby="firstName-error"
339
- />
340
- {showError('firstName') && (
341
- <span className="contact__error" id="firstName-error">
342
- {showError('firstName')}
343
- </span>
344
- )}
345
- </label>
346
-
347
- <label className="contact__form__group contact__form__group--3">
348
- <span className="contact__form__label">Achternaam*</span>
349
- <input
350
- type="text"
351
- className="contact__input"
352
- placeholder="Enter your last name"
353
- aria-label="Enter your last name"
354
- value={values.lastName}
355
- onChange={(e) => setField('lastName', e.target.value)}
356
- onBlur={() => onBlur('lastName')}
357
- aria-invalid={!!showError('lastName')}
358
- aria-describedby="lastName-error"
359
- />
360
- {showError('lastName') && (
361
- <span className="contact__error" id="lastName-error">
362
- {showError('lastName')}
363
- </span>
364
- )}
365
- </label>
366
-
367
- <label className="contact__form__group contact__form__group--3">
368
- <span className="contact__form__label">Geboortedatum*</span>
369
- <input
370
- type="date"
371
- className="contact__input"
372
- aria-label="Enter your date of birth"
373
- value={values.dateOfBirth}
374
- onChange={(e) => setField('dateOfBirth', e.target.value)}
375
- onBlur={() => onBlur('dateOfBirth')}
376
- aria-invalid={!!showError('dateOfBirth')}
377
- aria-describedby="dateOfBirth-error"
378
- />
379
- {showError('dateOfBirth') && (
380
- <span className="contact__error" id="dateOfBirth-error">
381
- {showError('dateOfBirth')}
382
- </span>
383
- )}
384
- </label>
385
-
386
- <label className="contact__form__group contact__form__group--3">
387
- <span className="contact__form__label">Nationaliteit*</span>
388
-
389
- <div className={`contact__dropdown ${showError('nationality') ? 'contact__dropdown--error' : ''}`}>
390
- <button
391
- type="button"
392
- className="contact__dropdown__trigger"
393
- aria-haspopup="listbox"
394
- aria-expanded={isNationalityOpen}
395
- onClick={() => setIsNationalityOpen((o) => !o)}
396
- onBlur={() => {
397
- setIsNationalityOpen(false);
398
- onBlur('nationality');
399
- }}>
400
- <span>{nationalityOptions.find((o) => o.value === values.nationality)?.label ?? 'Selecteer nationaliteit'}</span>
401
-
402
- <Icon name="ui-chevron" width={16} height={16} />
403
- </button>
404
-
405
- {isNationalityOpen && (
406
- <ul className="contact__dropdown__menu" role="listbox">
407
- {nationalityOptions.map((option) => (
408
- <li key={option.value}>
409
- <button
410
- type="button"
411
- className={`contact__dropdown__option ${values.nationality === option.value ? 'contact__dropdown__option--active' : ''}`}
412
- role="option"
413
- aria-selected={values.nationality === option.value}
414
- onMouseDown={() => {
415
- // onMouseDown prevents blur-before-click
416
- setField('nationality', option.value);
417
- setIsNationalityOpen(false);
418
- }}>
419
- {option.label}
420
- </button>
421
- </li>
422
- ))}
423
- </ul>
424
- )}
425
- </div>
426
-
427
- {showError('nationality') && (
428
- <span className="contact__error" id="nationality-error">
429
- {showError('nationality')}
430
- </span>
431
- )}
432
- </label>
433
-
434
- <label className="contact__form__group contact__form__group--3">
435
- <span className="contact__form__label">Email*</span>
436
- <input
437
- type="email"
438
- className="contact__input"
439
- placeholder="Enter your email"
440
- aria-label="Enter your email"
441
- value={values.email}
442
- onChange={(e) => setField('email', e.target.value)}
443
- onBlur={() => onBlur('email')}
444
- aria-invalid={!!showError('email')}
445
- aria-describedby="email-error"
446
- />
447
- {showError('email') && (
448
- <span className="contact__error" id="email-error">
449
- {showError('email')}
450
- </span>
451
- )}
452
- </label>
453
-
454
- <label className="contact__form__group contact__form__group--3">
455
- <span className="contact__form__label">Telefoonnummer</span>
456
- <input
457
- type="tel"
458
- className="contact__input"
459
- placeholder="Enter your phone number"
460
- aria-label="Enter your phone number"
461
- value={values.phone}
462
- onChange={(e) => setField('phone', e.target.value)}
463
- onBlur={() => onBlur('phone')}
464
- aria-invalid={!!showError('phone')}
465
- aria-describedby="phone-error"
466
- />
467
- {showError('phone') && (
468
- <span className="contact__error" id="phone-error">
469
- {showError('phone')}
470
- </span>
471
- )}
472
- </label>
473
-
474
- <label className="contact__form__group contact__form__group--2">
475
- <span className="contact__form__label">Straat*</span>
476
- <input
477
- type="text"
478
- className="contact__input"
479
- placeholder="Straatnaam"
480
- aria-label="Straat"
481
- value={values.street}
482
- onChange={(e) => setField('street', e.target.value)}
483
- onBlur={() => onBlur('street')}
484
- aria-invalid={!!showError('street')}
485
- aria-describedby="street-error"
486
- />
487
- {showError('street') && (
488
- <span className="contact__error" id="street-error">
489
- {showError('street')}
490
- </span>
491
- )}
492
- </label>
493
-
494
- <label className="contact__form__group contact__form__group--4">
495
- <span className="contact__form__label">Nummer*</span>
496
- <input
497
- type="text"
498
- className="contact__input"
499
- placeholder="Nr"
500
- aria-label="Huisnummer"
501
- value={values.houseNumber}
502
- onChange={(e) => setField('houseNumber', e.target.value)}
503
- onBlur={() => onBlur('houseNumber')}
504
- aria-invalid={!!showError('houseNumber')}
505
- aria-describedby="houseNumber-error"
506
- />
507
- {showError('houseNumber') && (
508
- <span className="contact__error" id="houseNumber-error">
509
- {showError('houseNumber')}
510
- </span>
511
- )}
512
- </label>
513
-
514
- <label className="contact__form__group contact__form__group--4">
515
- <span className="contact__form__label">Bus</span>
516
- <input
517
- type="text"
518
- className="contact__input"
519
- placeholder="Bus"
520
- aria-label="Bus"
521
- value={values.box}
522
- onChange={(e) => setField('box', e.target.value)}
523
- onBlur={() => onBlur('box')}
524
- aria-invalid={!!showError('box')}
525
- aria-describedby="box-error"
526
- />
527
- {showError('box') && (
528
- <span className="contact__error" id="box-error">
529
- {showError('box')}
530
- </span>
531
- )}
532
- </label>
533
-
534
- <label className="contact__form__group contact__form__group--3">
535
- <span className="contact__form__label">Postcode*</span>
536
- <input
537
- type="text"
538
- className="contact__input"
539
- placeholder="Postcode"
540
- aria-label="Postcode"
541
- value={values.postalCode}
542
- onChange={(e) => setField('postalCode', e.target.value)}
543
- onBlur={() => onBlur('postalCode')}
544
- aria-invalid={!!showError('postalCode')}
545
- aria-describedby="postalCode-error"
546
- />
547
- {showError('postalCode') && (
548
- <span className="contact__error" id="postalCode-error">
549
- {showError('postalCode')}
550
- </span>
551
- )}
552
- </label>
553
-
554
- <label className="contact__form__group contact__form__group--3">
555
- <span className="contact__form__label">Woonplaats*</span>
556
- <input
557
- type="text"
558
- className="contact__input"
559
- placeholder="Woonplaats"
560
- aria-label="Woonplaats"
561
- value={values.city}
562
- onChange={(e) => setField('city', e.target.value)}
563
- onBlur={() => onBlur('city')}
564
- aria-invalid={!!showError('city')}
565
- aria-describedby="city-error"
566
- />
567
- {showError('city') && (
568
- <span className="contact__error" id="city-error">
569
- {showError('city')}
570
- </span>
571
- )}
572
- </label>
573
-
574
- <label className="contact__form__group contact__form__group--3">
575
- <span className="contact__form__label">Land*</span>
576
-
577
- <div className={`contact__dropdown ${showError('country') ? 'contact__dropdown--error' : ''}`}>
578
- <button
579
- type="button"
580
- className="contact__dropdown__trigger"
581
- aria-haspopup="listbox"
582
- aria-expanded={isCountryOpen}
583
- aria-describedby="country-error"
584
- onClick={() => setIsCountryOpen((o) => !o)}
585
- onBlur={() => {
586
- setIsCountryOpen(false);
587
- onBlur('country');
588
- }}>
589
- <span>{countryOptions.find((o) => o.value === values.country)?.label ?? 'Selecteer land'}</span>
590
- <Icon name="ui-chevron" width={16} height={16} />
591
- </button>
592
-
593
- {isCountryOpen && (
594
- <ul className="contact__dropdown__menu" role="listbox">
595
- {countryOptions.map((option) => (
596
- <li key={option.value}>
597
- <button
598
- type="button"
599
- className={`contact__dropdown__option ${values.country === option.value ? 'contact__dropdown__option--active' : ''}`}
600
- role="option"
601
- aria-selected={values.country === option.value}
602
- onMouseDown={() => {
603
- // Prevent blur-before-click
604
- setField('country', option.value);
605
- setIsCountryOpen(false);
606
- }}>
607
- {option.label}
608
- </button>
609
- </li>
610
- ))}
611
- </ul>
612
- )}
613
- </div>
614
-
615
- {showError('country') && (
616
- <span className="contact__error" id="country-error">
617
- {showError('country')}
618
- </span>
619
- )}
620
- </label>
621
- </div>
622
- </div>
623
-
624
- <div className="contact__card">
625
- <div className="contact__title">
626
- <Icon name="ui-user" width={24} height={24} />
627
- <h4>Reiziger 2</h4>
628
- <span>volwassenen</span>
629
- </div>
630
-
631
- <div className="contact__radio" role="group" aria-labelledby="gender-label" aria-invalid={!!showError('gender1')} aria-describedby="gender-error">
632
- <span id="gender-label">Geslacht*</span>
633
-
634
- <div className="radiobutton-group">
635
- <div className="radiobutton">
636
- <label className="radiobutton__label">
637
- <input
638
- type="radio"
639
- name="gender2"
640
- value="female"
641
- className="radiobutton__input"
642
- checked={values.gender2 === 'female'}
643
- onChange={() => setField('gender2', 'female')}
644
- onBlur={() => onBlur('gender2')}
645
- />
646
- <span>Vrouw</span>
647
- </label>
648
- </div>
649
-
650
- <div className="radiobutton">
651
- <label className="radiobutton__label">
652
- <input
653
- type="radio"
654
- name="gender2"
655
- value="male"
656
- className="radiobutton__input"
657
- checked={values.gender2 === 'male'}
658
- onChange={() => setField('gender2', 'male')}
659
- onBlur={() => onBlur('gender2')}
660
- />
661
- <span>Man</span>
662
- </label>
663
- </div>
664
-
665
- <div className="radiobutton">
666
- <label className="radiobutton__label">
667
- <input
668
- type="radio"
669
- name="gender2"
670
- value="other"
671
- className="radiobutton__input"
672
- checked={values.gender2 === 'other'}
673
- onChange={() => setField('gender2', 'other')}
674
- onBlur={() => onBlur('gender2')}
675
- />
676
- <span>Anders</span>
677
- </label>
678
- </div>
679
- </div>
680
-
681
- {showError('gender2') && (
682
- <span className="contact__radio--error" id="gender-error">
683
- {showError('gender2')}
684
- </span>
685
- )}
686
- </div>
687
-
688
- <div className="contact__form">
689
- <label className="contact__form__group contact__form__group--2">
690
- <span className="contact__form__label">Voornaam*</span>
691
- <input
692
- type="text"
693
- className="contact__input"
694
- placeholder="Enter your name"
695
- aria-label="Enter your name"
696
- value={values.firstName}
697
- onChange={(e) => setField('firstName', e.target.value)}
698
- onBlur={() => onBlur('firstName')}
699
- aria-invalid={!!showError('firstName')}
700
- aria-describedby="firstName-error"
701
- />
702
- {showError('firstName') && (
703
- <span className="contact__error" id="firstName-error">
704
- {showError('firstName')}
705
- </span>
706
- )}
707
- </label>
708
-
709
- <label className="contact__form__group contact__form__group--2">
710
- <span className="contact__form__label">Achternaam*</span>
711
- <input
712
- type="text"
713
- className="contact__input"
714
- placeholder="Enter your last name"
715
- aria-label="Enter your last name"
716
- value={values.lastName}
717
- onChange={(e) => setField('lastName', e.target.value)}
718
- onBlur={() => onBlur('lastName')}
719
- aria-invalid={!!showError('lastName')}
720
- aria-describedby="lastName-error"
721
- />
722
- {showError('lastName') && (
723
- <span className="contact__error" id="lastName-error">
724
- {showError('lastName')}
725
- </span>
726
- )}
727
- </label>
728
-
729
- <label className="contact__form__group contact__form__group--2">
730
- <span className="contact__form__label">Geboortedatum*</span>
731
- <input
732
- type="date"
733
- className="contact__input"
734
- aria-label="Enter your date of birth"
735
- value={values.dateOfBirth}
736
- onChange={(e) => setField('dateOfBirth', e.target.value)}
737
- onBlur={() => onBlur('dateOfBirth')}
738
- aria-invalid={!!showError('dateOfBirth')}
739
- aria-describedby="dateOfBirth-error"
740
- />
741
- {showError('dateOfBirth') && (
742
- <span className="contact__error" id="dateOfBirth-error">
743
- {showError('dateOfBirth')}
744
- </span>
745
- )}
746
- </label>
747
-
748
- <label className="contact__form__group contact__form__group--2">
749
- <span className="contact__form__label">Nationaliteit*</span>
750
-
751
- <div className={`contact__dropdown ${showError('nationality') ? 'contact__dropdown--error' : ''}`}>
752
- <button
753
- type="button"
754
- className="contact__dropdown__trigger"
755
- aria-haspopup="listbox"
756
- aria-expanded={isNationalityOpen}
757
- onClick={() => setIsNationalityOpen((o) => !o)}
758
- onBlur={() => {
759
- setIsNationalityOpen(false);
760
- onBlur('nationality');
761
- }}>
762
- <span>{nationalityOptions.find((o) => o.value === values.nationality)?.label ?? 'Selecteer nationaliteit'}</span>
763
-
764
- <Icon name="ui-chevron" width={16} height={16} />
765
- </button>
766
-
767
- {isNationalityOpen && (
768
- <ul className="contact__dropdown__menu" role="listbox">
769
- {nationalityOptions.map((option) => (
770
- <li key={option.value}>
771
- <button
772
- type="button"
773
- className={`contact__dropdown__option ${values.nationality === option.value ? 'contact__dropdown__option--active' : ''}`}
774
- role="option"
775
- aria-selected={values.nationality === option.value}
776
- onMouseDown={() => {
777
- // onMouseDown prevents blur-before-click
778
- setField('nationality', option.value);
779
- setIsNationalityOpen(false);
780
- }}>
781
- {option.label}
782
- </button>
783
- </li>
784
- ))}
785
- </ul>
786
- )}
787
- </div>
788
-
789
- {showError('nationality') && (
790
- <span className="contact__error" id="nationality-error">
791
- {showError('nationality')}
792
- </span>
793
- )}
794
- </label>
795
- </div>
796
- </div>
797
-
798
- <div className="contact__form__actions">
799
- <button type="submit" className="cta cta--primary">
800
- Send message
801
- </button>
802
- </div>
803
- </form>
804
- </div>
805
- </div>
806
- );
807
- };
808
-
809
- export default PersonalContactForm;
1
+ import React, { useMemo, useState } from 'react';
2
+ import Icon from '../../shared/components/icon';
3
+
4
+ type ContactValues = {
5
+ firstName: string;
6
+ lastName: string;
7
+ dateOfBirth: string;
8
+ nationality: string;
9
+ email: string;
10
+ phone: string;
11
+ message: string;
12
+ street: string;
13
+ houseNumber: string;
14
+ box: string;
15
+ postalCode: string;
16
+ city: string;
17
+ country: string;
18
+ // traveler 1
19
+ bookingType1: 'leisure' | 'business' | '';
20
+ gender1: 'female' | 'male' | 'other' | '';
21
+
22
+ // traveler 2
23
+ bookingType2: 'leisure' | 'business' | '';
24
+ gender2: 'female' | 'male' | 'other' | '';
25
+ };
26
+
27
+ type ContactErrors = Partial<Record<keyof ContactValues, string>>;
28
+ // const [touched, setTouched] = useState<Partial<Record<keyof ContactValues, boolean>>>({});
29
+
30
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
31
+ const phoneRegex = /^[+()\-.\s0-9]{8,20}$/;
32
+
33
+ // Small helper: checks YYYY-MM-DD parses to a real date
34
+ const isValidISODate = (value: string) => {
35
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return false;
36
+ const d = new Date(value);
37
+ return !Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) === value;
38
+ };
39
+
40
+ // You can expand this list later (or load from API)
41
+ const nationalityOptions = [
42
+ { value: '', label: 'Selecteer nationaliteit' },
43
+ { value: 'BE', label: 'Belgisch' },
44
+ { value: 'NL', label: 'Nederlands' },
45
+ { value: 'FR', label: 'Frans' },
46
+ { value: 'DE', label: 'Duits' },
47
+ { value: 'UK', label: 'Brits' },
48
+ { value: 'US', label: 'Amerikaans' }
49
+ ];
50
+
51
+ const countryOptions = [
52
+ { value: '', label: 'Selecteer land' },
53
+ { value: 'BE', label: 'België' },
54
+ { value: 'NL', label: 'Nederland' },
55
+ { value: 'FR', label: 'Frankrijk' },
56
+ { value: 'DE', label: 'Duitsland' },
57
+ { value: 'LU', label: 'Luxemburg' },
58
+ { value: 'UK', label: 'Verenigd Koninkrijk' }
59
+ ];
60
+
61
+ const PersonalContactForm: React.FC = () => {
62
+ const [values, setValues] = useState<ContactValues>({
63
+ firstName: '',
64
+ lastName: '',
65
+ dateOfBirth: '',
66
+ nationality: '',
67
+ email: '',
68
+ phone: '',
69
+ message: '',
70
+ street: '',
71
+ houseNumber: '',
72
+ box: '',
73
+ postalCode: '',
74
+ city: '',
75
+ country: '',
76
+ bookingType1: '',
77
+ gender1: '',
78
+ bookingType2: '',
79
+ gender2: ''
80
+ });
81
+
82
+ const [touched, setTouched] = useState<Partial<Record<keyof ContactValues, boolean>>>({});
83
+ const [errors, setErrors] = useState<ContactErrors>({});
84
+ const [submitted, setSubmitted] = useState(false);
85
+ const [isNationalityOpen, setIsNationalityOpen] = useState(false);
86
+ const [isCountryOpen, setIsCountryOpen] = useState(false);
87
+
88
+ const postalCodeRegex = /^[0-9A-Za-z\s-]{3,10}$/;
89
+
90
+ const validate = (v: ContactValues): ContactErrors => {
91
+ const e: ContactErrors = {};
92
+
93
+ if (!v.firstName.trim()) e.firstName = 'Voornaam is verplicht.';
94
+ if (!v.lastName.trim()) e.lastName = 'Achternaam is verplicht.';
95
+
96
+ if (!v.dateOfBirth.trim()) e.dateOfBirth = 'Geboortedatum is verplicht.';
97
+ else if (!isValidISODate(v.dateOfBirth.trim())) e.dateOfBirth = 'Vul een geldige geboortedatum in.';
98
+
99
+ if (!v.nationality.trim()) e.nationality = 'Nationaliteit is verplicht.';
100
+
101
+ if (!v.email.trim()) e.email = 'Email is verplicht.';
102
+ else if (!emailRegex.test(v.email.trim())) e.email = 'Vul een geldig e-mailadres in.';
103
+
104
+ if (v.phone.trim() && !phoneRegex.test(v.phone.trim())) {
105
+ e.phone = 'Vul een geldig telefoonnummer in.';
106
+ }
107
+
108
+ if (!v.message.trim()) e.message = 'Bericht is verplicht.';
109
+ else if (v.message.trim().length < 10) e.message = 'Bericht moet minstens 10 tekens zijn.';
110
+
111
+ if (!v.street.trim()) e.street = 'Straat is verplicht.';
112
+ if (!v.houseNumber.trim()) e.houseNumber = 'Nummer is verplicht.';
113
+
114
+ if (!v.postalCode.trim()) e.postalCode = 'Postcode is verplicht.';
115
+ else if (!postalCodeRegex.test(v.postalCode.trim())) e.postalCode = 'Vul een geldige postcode in.';
116
+
117
+ if (!v.city.trim()) e.city = 'Woonplaats is verplicht.';
118
+ if (!v.country.trim()) e.country = 'Land is verplicht.';
119
+
120
+ if (!v.gender1) e.gender1 = 'Geslacht is verplicht.';
121
+ if (!v.gender2) e.gender2 = 'Geslacht is verplicht.';
122
+
123
+ if (!v.bookingType1) e.bookingType1 = 'Type boeking is verplicht.';
124
+ if (!v.bookingType2) e.bookingType2 = 'Type boeking is verplicht.';
125
+
126
+ return e;
127
+ };
128
+
129
+ const currentErrors = useMemo(() => validate(values), [values]);
130
+
131
+ const setField = <K extends keyof ContactValues>(key: K, val: ContactValues[K]) => {
132
+ setValues((p) => ({ ...p, [key]: val }));
133
+ if (submitted || touched[key]) {
134
+ setErrors(validate({ ...values, [key]: val } as ContactValues));
135
+ }
136
+ };
137
+
138
+ const onBlur = (key: keyof ContactValues) => {
139
+ setTouched((p) => ({ ...p, [key]: true }));
140
+ setErrors(validate(values));
141
+ };
142
+
143
+ const onSubmit = (e: React.FormEvent) => {
144
+ e.preventDefault();
145
+ setSubmitted(true);
146
+
147
+ const eMap = validate(values);
148
+ setErrors(eMap);
149
+
150
+ if (Object.keys(eMap).length > 0) return;
151
+
152
+ console.log('Contact form submit:', values);
153
+
154
+ setValues({
155
+ firstName: '',
156
+ lastName: '',
157
+ dateOfBirth: '',
158
+ nationality: '',
159
+ email: '',
160
+ phone: '',
161
+ message: '',
162
+ street: '',
163
+ houseNumber: '',
164
+ box: '',
165
+ postalCode: '',
166
+ city: '',
167
+ country: '',
168
+ bookingType1: '',
169
+ gender1: '',
170
+ bookingType2: '',
171
+ gender2: ''
172
+ });
173
+ setTouched({});
174
+ setErrors({});
175
+ setSubmitted(false);
176
+ };
177
+
178
+ const showError = (key: keyof ContactValues) => {
179
+ const shouldShow = submitted || touched[key];
180
+ return shouldShow ? errors[key] : undefined;
181
+ };
182
+
183
+ return (
184
+ <div className="content content--background">
185
+ <div className="content__container content__container--medium">
186
+ <div className="content__title__row">
187
+ <h2 className="content__title">Persoonlijke informatie</h2>
188
+ </div>
189
+
190
+ <form className="contact" noValidate onSubmit={onSubmit}>
191
+ <div className="contact__card contact__card--headbooker">
192
+ <div className="contact__title">
193
+ <Icon name="ui-info-circle" width={24} height={24} />
194
+ <h4>Gaat de hoofdboeker mee op reis?</h4>
195
+ </div>
196
+
197
+ <div className="contact__form">
198
+ <div className="radiobutton-group">
199
+ <div className="radiobutton">
200
+ <label className="radiobutton__label">
201
+ <input type="radio" name="headBooker" value="yes" className="radiobutton__input" defaultChecked={true} />
202
+ <span>Ja</span>
203
+ </label>
204
+ </div>
205
+
206
+ <div className="radiobutton">
207
+ <label className="radiobutton__label">
208
+ <input type="radio" name="headBooker" value="no" className="radiobutton__input" />
209
+ <span>Nee</span>
210
+ </label>
211
+ </div>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ <div className="contact__card">
216
+ <div className="contact__title">
217
+ <Icon name="ui-user" width={24} height={24} />
218
+ <h4>Reiziger 1</h4>
219
+ <span>volwassenen, hoofdboeker</span>
220
+ </div>
221
+
222
+ <div
223
+ className="contact__radio"
224
+ role="group"
225
+ aria-labelledby="bookingType-label"
226
+ aria-invalid={!!showError('bookingType1')}
227
+ aria-describedby="bookingType-error">
228
+ <span id="bookingType-label">Type boeking{/** add * if required */}</span>
229
+
230
+ <div className="radiobutton-group">
231
+ <div className="radiobutton">
232
+ <label className="radiobutton__label">
233
+ <input
234
+ type="radio"
235
+ name="bookingType1"
236
+ value="leisure"
237
+ className="radiobutton__input"
238
+ checked={values.bookingType1 === 'leisure'}
239
+ onChange={() => setField('bookingType1', 'leisure')}
240
+ onBlur={() => onBlur('bookingType1')}
241
+ />
242
+ <span>Plezier</span>
243
+ </label>
244
+ </div>
245
+
246
+ <div className="radiobutton">
247
+ <label className="radiobutton__label">
248
+ <input
249
+ type="radio"
250
+ name="bookingType1"
251
+ value="business"
252
+ className="radiobutton__input"
253
+ checked={values.bookingType1 === 'business'}
254
+ onChange={() => setField('bookingType1', 'business')}
255
+ onBlur={() => onBlur('bookingType1')}
256
+ />
257
+ <span>Zakelijk</span>
258
+ </label>
259
+ </div>
260
+ </div>
261
+
262
+ {showError('bookingType1') && (
263
+ <span className="contact__radio--error" id="bookingType-error">
264
+ {showError('bookingType1')}
265
+ </span>
266
+ )}
267
+ </div>
268
+
269
+ <div className="contact__radio" role="group" aria-labelledby="gender-label" aria-invalid={!!showError('gender1')} aria-describedby="gender-error">
270
+ <span id="gender-label">Geslacht*</span>
271
+
272
+ <div className="radiobutton-group">
273
+ <div className="radiobutton">
274
+ <label className="radiobutton__label">
275
+ <input
276
+ type="radio"
277
+ name="gender1"
278
+ value="female"
279
+ className="radiobutton__input"
280
+ checked={values.gender1 === 'female'}
281
+ onChange={() => setField('gender1', 'female')}
282
+ onBlur={() => onBlur('gender1')}
283
+ />
284
+ <span>Vrouw</span>
285
+ </label>
286
+ </div>
287
+
288
+ <div className="radiobutton">
289
+ <label className="radiobutton__label">
290
+ <input
291
+ type="radio"
292
+ name="gender1"
293
+ value="male"
294
+ className="radiobutton__input"
295
+ checked={values.gender1 === 'male'}
296
+ onChange={() => setField('gender1', 'male')}
297
+ onBlur={() => onBlur('gender1')}
298
+ />
299
+ <span>Man</span>
300
+ </label>
301
+ </div>
302
+
303
+ <div className="radiobutton">
304
+ <label className="radiobutton__label">
305
+ <input
306
+ type="radio"
307
+ name="gender1"
308
+ value="other"
309
+ className="radiobutton__input"
310
+ checked={values.gender1 === 'other'}
311
+ onChange={() => setField('gender1', 'other')}
312
+ onBlur={() => onBlur('gender1')}
313
+ />
314
+ <span>Anders</span>
315
+ </label>
316
+ </div>
317
+ </div>
318
+
319
+ {showError('gender1') && (
320
+ <span className="contact__radio--error" id="gender-error">
321
+ {showError('gender1')}
322
+ </span>
323
+ )}
324
+ </div>
325
+
326
+ <div className="contact__form">
327
+ <label className="contact__form__group contact__form__group--33">
328
+ <span className="contact__form__label">Voornaam*</span>
329
+ <input
330
+ type="text"
331
+ className="contact__input"
332
+ placeholder="Enter your name"
333
+ aria-label="Enter your name"
334
+ value={values.firstName}
335
+ onChange={(e) => setField('firstName', e.target.value)}
336
+ onBlur={() => onBlur('firstName')}
337
+ aria-invalid={!!showError('firstName')}
338
+ aria-describedby="firstName-error"
339
+ />
340
+ {showError('firstName') && (
341
+ <span className="contact__error" id="firstName-error">
342
+ {showError('firstName')}
343
+ </span>
344
+ )}
345
+ </label>
346
+
347
+ <label className="contact__form__group contact__form__group--33">
348
+ <span className="contact__form__label">Achternaam*</span>
349
+ <input
350
+ type="text"
351
+ className="contact__input"
352
+ placeholder="Enter your last name"
353
+ aria-label="Enter your last name"
354
+ value={values.lastName}
355
+ onChange={(e) => setField('lastName', e.target.value)}
356
+ onBlur={() => onBlur('lastName')}
357
+ aria-invalid={!!showError('lastName')}
358
+ aria-describedby="lastName-error"
359
+ />
360
+ {showError('lastName') && (
361
+ <span className="contact__error" id="lastName-error">
362
+ {showError('lastName')}
363
+ </span>
364
+ )}
365
+ </label>
366
+
367
+ <label className="contact__form__group contact__form__group--33">
368
+ <span className="contact__form__label">Geboortedatum*</span>
369
+ <input
370
+ type="date"
371
+ className="contact__input"
372
+ aria-label="Enter your date of birth"
373
+ value={values.dateOfBirth}
374
+ onChange={(e) => setField('dateOfBirth', e.target.value)}
375
+ onBlur={() => onBlur('dateOfBirth')}
376
+ aria-invalid={!!showError('dateOfBirth')}
377
+ aria-describedby="dateOfBirth-error"
378
+ />
379
+ {showError('dateOfBirth') && (
380
+ <span className="contact__error" id="dateOfBirth-error">
381
+ {showError('dateOfBirth')}
382
+ </span>
383
+ )}
384
+ </label>
385
+
386
+ <label className="contact__form__group contact__form__group--33">
387
+ <span className="contact__form__label">Nationaliteit*</span>
388
+
389
+ <div className={`contact__dropdown ${showError('nationality') ? 'contact__dropdown--error' : ''}`}>
390
+ <button
391
+ type="button"
392
+ className="contact__dropdown__trigger"
393
+ aria-haspopup="listbox"
394
+ aria-expanded={isNationalityOpen}
395
+ onClick={() => setIsNationalityOpen((o) => !o)}
396
+ onBlur={() => {
397
+ setIsNationalityOpen(false);
398
+ onBlur('nationality');
399
+ }}>
400
+ <span>{nationalityOptions.find((o) => o.value === values.nationality)?.label ?? 'Selecteer nationaliteit'}</span>
401
+
402
+ <Icon name="ui-chevron" width={16} height={16} />
403
+ </button>
404
+
405
+ {isNationalityOpen && (
406
+ <ul className="contact__dropdown__menu" role="listbox">
407
+ {nationalityOptions.map((option) => (
408
+ <li key={option.value}>
409
+ <button
410
+ type="button"
411
+ className={`contact__dropdown__option ${values.nationality === option.value ? 'contact__dropdown__option--active' : ''}`}
412
+ role="option"
413
+ aria-selected={values.nationality === option.value}
414
+ onMouseDown={() => {
415
+ // onMouseDown prevents blur-before-click
416
+ setField('nationality', option.value);
417
+ setIsNationalityOpen(false);
418
+ }}>
419
+ {option.label}
420
+ </button>
421
+ </li>
422
+ ))}
423
+ </ul>
424
+ )}
425
+ </div>
426
+
427
+ {showError('nationality') && (
428
+ <span className="contact__error" id="nationality-error">
429
+ {showError('nationality')}
430
+ </span>
431
+ )}
432
+ </label>
433
+
434
+ <label className="contact__form__group contact__form__group--33">
435
+ <span className="contact__form__label">Email*</span>
436
+ <input
437
+ type="email"
438
+ className="contact__input"
439
+ placeholder="Enter your email"
440
+ aria-label="Enter your email"
441
+ value={values.email}
442
+ onChange={(e) => setField('email', e.target.value)}
443
+ onBlur={() => onBlur('email')}
444
+ aria-invalid={!!showError('email')}
445
+ aria-describedby="email-error"
446
+ />
447
+ {showError('email') && (
448
+ <span className="contact__error" id="email-error">
449
+ {showError('email')}
450
+ </span>
451
+ )}
452
+ </label>
453
+
454
+ <label className="contact__form__group contact__form__group--33">
455
+ <span className="contact__form__label">Telefoonnummer</span>
456
+ <input
457
+ type="tel"
458
+ className="contact__input"
459
+ placeholder="Enter your phone number"
460
+ aria-label="Enter your phone number"
461
+ value={values.phone}
462
+ onChange={(e) => setField('phone', e.target.value)}
463
+ onBlur={() => onBlur('phone')}
464
+ aria-invalid={!!showError('phone')}
465
+ aria-describedby="phone-error"
466
+ />
467
+ {showError('phone') && (
468
+ <span className="contact__error" id="phone-error">
469
+ {showError('phone')}
470
+ </span>
471
+ )}
472
+ </label>
473
+
474
+ <label className="contact__form__group contact__form__group--55">
475
+ <span className="contact__form__label">Straat*</span>
476
+ <input
477
+ type="text"
478
+ className="contact__input"
479
+ placeholder="Straatnaam"
480
+ aria-label="Straat"
481
+ value={values.street}
482
+ onChange={(e) => setField('street', e.target.value)}
483
+ onBlur={() => onBlur('street')}
484
+ aria-invalid={!!showError('street')}
485
+ aria-describedby="street-error"
486
+ />
487
+ {showError('street') && (
488
+ <span className="contact__error" id="street-error">
489
+ {showError('street')}
490
+ </span>
491
+ )}
492
+ </label>
493
+
494
+ <label className="contact__form__group contact__form__group--25">
495
+ <span className="contact__form__label">Nummer*</span>
496
+ <input
497
+ type="text"
498
+ className="contact__input"
499
+ placeholder="Nr"
500
+ aria-label="Huisnummer"
501
+ value={values.houseNumber}
502
+ onChange={(e) => setField('houseNumber', e.target.value)}
503
+ onBlur={() => onBlur('houseNumber')}
504
+ aria-invalid={!!showError('houseNumber')}
505
+ aria-describedby="houseNumber-error"
506
+ />
507
+ {showError('houseNumber') && (
508
+ <span className="contact__error" id="houseNumber-error">
509
+ {showError('houseNumber')}
510
+ </span>
511
+ )}
512
+ </label>
513
+
514
+ <label className="contact__form__group contact__form__group--25">
515
+ <span className="contact__form__label">Bus</span>
516
+ <input
517
+ type="text"
518
+ className="contact__input"
519
+ placeholder="Bus"
520
+ aria-label="Bus"
521
+ value={values.box}
522
+ onChange={(e) => setField('box', e.target.value)}
523
+ onBlur={() => onBlur('box')}
524
+ aria-invalid={!!showError('box')}
525
+ aria-describedby="box-error"
526
+ />
527
+ {showError('box') && (
528
+ <span className="contact__error" id="box-error">
529
+ {showError('box')}
530
+ </span>
531
+ )}
532
+ </label>
533
+
534
+ <label className="contact__form__group contact__form__group--25">
535
+ <span className="contact__form__label">Postcode*</span>
536
+ <input
537
+ type="text"
538
+ className="contact__input"
539
+ placeholder="Postcode"
540
+ aria-label="Postcode"
541
+ value={values.postalCode}
542
+ onChange={(e) => setField('postalCode', e.target.value)}
543
+ onBlur={() => onBlur('postalCode')}
544
+ aria-invalid={!!showError('postalCode')}
545
+ aria-describedby="postalCode-error"
546
+ />
547
+ {showError('postalCode') && (
548
+ <span className="contact__error" id="postalCode-error">
549
+ {showError('postalCode')}
550
+ </span>
551
+ )}
552
+ </label>
553
+
554
+ <label className="contact__form__group contact__form__group--33">
555
+ <span className="contact__form__label">Woonplaats*</span>
556
+ <input
557
+ type="text"
558
+ className="contact__input"
559
+ placeholder="Woonplaats"
560
+ aria-label="Woonplaats"
561
+ value={values.city}
562
+ onChange={(e) => setField('city', e.target.value)}
563
+ onBlur={() => onBlur('city')}
564
+ aria-invalid={!!showError('city')}
565
+ aria-describedby="city-error"
566
+ />
567
+ {showError('city') && (
568
+ <span className="contact__error" id="city-error">
569
+ {showError('city')}
570
+ </span>
571
+ )}
572
+ </label>
573
+
574
+ <label className="contact__form__group contact__form__group--33">
575
+ <span className="contact__form__label">Land*</span>
576
+
577
+ <div className={`contact__dropdown ${showError('country') ? 'contact__dropdown--error' : ''}`}>
578
+ <button
579
+ type="button"
580
+ className="contact__dropdown__trigger"
581
+ aria-haspopup="listbox"
582
+ aria-expanded={isCountryOpen}
583
+ aria-describedby="country-error"
584
+ onClick={() => setIsCountryOpen((o) => !o)}
585
+ onBlur={() => {
586
+ setIsCountryOpen(false);
587
+ onBlur('country');
588
+ }}>
589
+ <span>{countryOptions.find((o) => o.value === values.country)?.label ?? 'Selecteer land'}</span>
590
+ <Icon name="ui-chevron" width={16} height={16} />
591
+ </button>
592
+
593
+ {isCountryOpen && (
594
+ <ul className="contact__dropdown__menu" role="listbox">
595
+ {countryOptions.map((option) => (
596
+ <li key={option.value}>
597
+ <button
598
+ type="button"
599
+ className={`contact__dropdown__option ${values.country === option.value ? 'contact__dropdown__option--active' : ''}`}
600
+ role="option"
601
+ aria-selected={values.country === option.value}
602
+ onMouseDown={() => {
603
+ // Prevent blur-before-click
604
+ setField('country', option.value);
605
+ setIsCountryOpen(false);
606
+ }}>
607
+ {option.label}
608
+ </button>
609
+ </li>
610
+ ))}
611
+ </ul>
612
+ )}
613
+ </div>
614
+
615
+ {showError('country') && (
616
+ <span className="contact__error" id="country-error">
617
+ {showError('country')}
618
+ </span>
619
+ )}
620
+ </label>
621
+ </div>
622
+ </div>
623
+
624
+ <div className="contact__card">
625
+ <div className="contact__title">
626
+ <Icon name="ui-user" width={24} height={24} />
627
+ <h4>Reiziger 2</h4>
628
+ <span>volwassenen</span>
629
+ </div>
630
+
631
+ <div className="contact__radio" role="group" aria-labelledby="gender-label" aria-invalid={!!showError('gender1')} aria-describedby="gender-error">
632
+ <span id="gender-label">Geslacht*</span>
633
+
634
+ <div className="radiobutton-group">
635
+ <div className="radiobutton">
636
+ <label className="radiobutton__label">
637
+ <input
638
+ type="radio"
639
+ name="gender2"
640
+ value="female"
641
+ className="radiobutton__input"
642
+ checked={values.gender2 === 'female'}
643
+ onChange={() => setField('gender2', 'female')}
644
+ onBlur={() => onBlur('gender2')}
645
+ />
646
+ <span>Vrouw</span>
647
+ </label>
648
+ </div>
649
+
650
+ <div className="radiobutton">
651
+ <label className="radiobutton__label">
652
+ <input
653
+ type="radio"
654
+ name="gender2"
655
+ value="male"
656
+ className="radiobutton__input"
657
+ checked={values.gender2 === 'male'}
658
+ onChange={() => setField('gender2', 'male')}
659
+ onBlur={() => onBlur('gender2')}
660
+ />
661
+ <span>Man</span>
662
+ </label>
663
+ </div>
664
+
665
+ <div className="radiobutton">
666
+ <label className="radiobutton__label">
667
+ <input
668
+ type="radio"
669
+ name="gender2"
670
+ value="other"
671
+ className="radiobutton__input"
672
+ checked={values.gender2 === 'other'}
673
+ onChange={() => setField('gender2', 'other')}
674
+ onBlur={() => onBlur('gender2')}
675
+ />
676
+ <span>Anders</span>
677
+ </label>
678
+ </div>
679
+ </div>
680
+
681
+ {showError('gender2') && (
682
+ <span className="contact__radio--error" id="gender-error">
683
+ {showError('gender2')}
684
+ </span>
685
+ )}
686
+ </div>
687
+
688
+ <div className="contact__form">
689
+ <label className="contact__form__group contact__form__group--50">
690
+ <span className="contact__form__label">Voornaam*</span>
691
+ <input
692
+ type="text"
693
+ className="contact__input"
694
+ placeholder="Enter your name"
695
+ aria-label="Enter your name"
696
+ value={values.firstName}
697
+ onChange={(e) => setField('firstName', e.target.value)}
698
+ onBlur={() => onBlur('firstName')}
699
+ aria-invalid={!!showError('firstName')}
700
+ aria-describedby="firstName-error"
701
+ />
702
+ {showError('firstName') && (
703
+ <span className="contact__error" id="firstName-error">
704
+ {showError('firstName')}
705
+ </span>
706
+ )}
707
+ </label>
708
+
709
+ <label className="contact__form__group contact__form__group--50">
710
+ <span className="contact__form__label">Achternaam*</span>
711
+ <input
712
+ type="text"
713
+ className="contact__input"
714
+ placeholder="Enter your last name"
715
+ aria-label="Enter your last name"
716
+ value={values.lastName}
717
+ onChange={(e) => setField('lastName', e.target.value)}
718
+ onBlur={() => onBlur('lastName')}
719
+ aria-invalid={!!showError('lastName')}
720
+ aria-describedby="lastName-error"
721
+ />
722
+ {showError('lastName') && (
723
+ <span className="contact__error" id="lastName-error">
724
+ {showError('lastName')}
725
+ </span>
726
+ )}
727
+ </label>
728
+
729
+ <label className="contact__form__group contact__form__group--50">
730
+ <span className="contact__form__label">Geboortedatum*</span>
731
+ <input
732
+ type="date"
733
+ className="contact__input"
734
+ aria-label="Enter your date of birth"
735
+ value={values.dateOfBirth}
736
+ onChange={(e) => setField('dateOfBirth', e.target.value)}
737
+ onBlur={() => onBlur('dateOfBirth')}
738
+ aria-invalid={!!showError('dateOfBirth')}
739
+ aria-describedby="dateOfBirth-error"
740
+ />
741
+ {showError('dateOfBirth') && (
742
+ <span className="contact__error" id="dateOfBirth-error">
743
+ {showError('dateOfBirth')}
744
+ </span>
745
+ )}
746
+ </label>
747
+
748
+ <label className="contact__form__group contact__form__group--50">
749
+ <span className="contact__form__label">Nationaliteit*</span>
750
+
751
+ <div className={`contact__dropdown ${showError('nationality') ? 'contact__dropdown--error' : ''}`}>
752
+ <button
753
+ type="button"
754
+ className="contact__dropdown__trigger"
755
+ aria-haspopup="listbox"
756
+ aria-expanded={isNationalityOpen}
757
+ onClick={() => setIsNationalityOpen((o) => !o)}
758
+ onBlur={() => {
759
+ setIsNationalityOpen(false);
760
+ onBlur('nationality');
761
+ }}>
762
+ <span>{nationalityOptions.find((o) => o.value === values.nationality)?.label ?? 'Selecteer nationaliteit'}</span>
763
+
764
+ <Icon name="ui-chevron" width={16} height={16} />
765
+ </button>
766
+
767
+ {isNationalityOpen && (
768
+ <ul className="contact__dropdown__menu" role="listbox">
769
+ {nationalityOptions.map((option) => (
770
+ <li key={option.value}>
771
+ <button
772
+ type="button"
773
+ className={`contact__dropdown__option ${values.nationality === option.value ? 'contact__dropdown__option--active' : ''}`}
774
+ role="option"
775
+ aria-selected={values.nationality === option.value}
776
+ onMouseDown={() => {
777
+ // onMouseDown prevents blur-before-click
778
+ setField('nationality', option.value);
779
+ setIsNationalityOpen(false);
780
+ }}>
781
+ {option.label}
782
+ </button>
783
+ </li>
784
+ ))}
785
+ </ul>
786
+ )}
787
+ </div>
788
+
789
+ {showError('nationality') && (
790
+ <span className="contact__error" id="nationality-error">
791
+ {showError('nationality')}
792
+ </span>
793
+ )}
794
+ </label>
795
+ </div>
796
+ </div>
797
+
798
+ <div className="contact__form__actions">
799
+ <button type="submit" className="cta cta--primary">
800
+ Send message
801
+ </button>
802
+ </div>
803
+ </form>
804
+ </div>
805
+ </div>
806
+ );
807
+ };
808
+
809
+ export default PersonalContactForm;