@voyant-travel/bookings-react 0.119.3

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 (602) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +87 -0
  3. package/dist/admin/booking-contract-dialog.d.ts +22 -0
  4. package/dist/admin/booking-contract-dialog.d.ts.map +1 -0
  5. package/dist/admin/booking-contract-dialog.js +161 -0
  6. package/dist/admin/booking-detail-host.d.ts +103 -0
  7. package/dist/admin/booking-detail-host.d.ts.map +1 -0
  8. package/dist/admin/booking-detail-host.js +127 -0
  9. package/dist/admin/booking-detail-skeleton.d.ts +7 -0
  10. package/dist/admin/booking-detail-skeleton.d.ts.map +1 -0
  11. package/dist/admin/booking-detail-skeleton.js +24 -0
  12. package/dist/admin/booking-documents-table.d.ts +13 -0
  13. package/dist/admin/booking-documents-table.d.ts.map +1 -0
  14. package/dist/admin/booking-documents-table.js +259 -0
  15. package/dist/admin/booking-invoice-sheet.d.ts +18 -0
  16. package/dist/admin/booking-invoice-sheet.d.ts.map +1 -0
  17. package/dist/admin/booking-invoice-sheet.js +101 -0
  18. package/dist/admin/booking-journey-host.d.ts +24 -0
  19. package/dist/admin/booking-journey-host.d.ts.map +1 -0
  20. package/dist/admin/booking-journey-host.js +278 -0
  21. package/dist/admin/bookings-host.d.ts +26 -0
  22. package/dist/admin/bookings-host.d.ts.map +1 -0
  23. package/dist/admin/bookings-host.js +18 -0
  24. package/dist/admin/bookings-list-skeleton.d.ts +10 -0
  25. package/dist/admin/bookings-list-skeleton.d.ts.map +1 -0
  26. package/dist/admin/bookings-list-skeleton.js +25 -0
  27. package/dist/admin/index.d.ts +273 -0
  28. package/dist/admin/index.d.ts.map +1 -0
  29. package/dist/admin/index.js +331 -0
  30. package/dist/admin/journey-billing-duplicate-warning.d.ts +3 -0
  31. package/dist/admin/journey-billing-duplicate-warning.d.ts.map +1 -0
  32. package/dist/admin/journey-billing-duplicate-warning.js +26 -0
  33. package/dist/admin/journey-departure-picker.d.ts +7 -0
  34. package/dist/admin/journey-departure-picker.d.ts.map +1 -0
  35. package/dist/admin/journey-departure-picker.js +100 -0
  36. package/dist/admin/journey-units-picker.d.ts +11 -0
  37. package/dist/admin/journey-units-picker.d.ts.map +1 -0
  38. package/dist/admin/journey-units-picker.js +60 -0
  39. package/dist/admin/journey-voucher-picker.d.ts +3 -0
  40. package/dist/admin/journey-voucher-picker.d.ts.map +1 -0
  41. package/dist/admin/journey-voucher-picker.js +71 -0
  42. package/dist/admin/pages/booking-compose-page.d.ts +9 -0
  43. package/dist/admin/pages/booking-compose-page.d.ts.map +1 -0
  44. package/dist/admin/pages/booking-compose-page.js +17 -0
  45. package/dist/admin/pages/booking-detail-page.d.ts +11 -0
  46. package/dist/admin/pages/booking-detail-page.d.ts.map +1 -0
  47. package/dist/admin/pages/booking-detail-page.js +14 -0
  48. package/dist/admin/pages/booking-journey-page.d.ts +12 -0
  49. package/dist/admin/pages/booking-journey-page.d.ts.map +1 -0
  50. package/dist/admin/pages/booking-journey-page.js +26 -0
  51. package/dist/admin/pages/booking-new-page.d.ts +15 -0
  52. package/dist/admin/pages/booking-new-page.d.ts.map +1 -0
  53. package/dist/admin/pages/booking-new-page.js +50 -0
  54. package/dist/admin/pages/bookings-index-page.d.ts +20 -0
  55. package/dist/admin/pages/bookings-index-page.d.ts.map +1 -0
  56. package/dist/admin/pages/bookings-index-page.js +18 -0
  57. package/dist/admin/person-bookings-widget.d.ts +13 -0
  58. package/dist/admin/person-bookings-widget.d.ts.map +1 -0
  59. package/dist/admin/person-bookings-widget.js +48 -0
  60. package/dist/admin/slots.d.ts +31 -0
  61. package/dist/admin/slots.d.ts.map +1 -0
  62. package/dist/admin/slots.js +30 -0
  63. package/dist/admin/use-booking-action-ledger-events.d.ts +15 -0
  64. package/dist/admin/use-booking-action-ledger-events.d.ts.map +1 -0
  65. package/dist/admin/use-booking-action-ledger-events.js +66 -0
  66. package/dist/client.d.ts +14 -0
  67. package/dist/client.d.ts.map +1 -0
  68. package/dist/client.js +59 -0
  69. package/dist/components/booking-activity-timeline.d.ts +32 -0
  70. package/dist/components/booking-activity-timeline.d.ts.map +1 -0
  71. package/dist/components/booking-activity-timeline.js +147 -0
  72. package/dist/components/booking-billing-dialog.d.ts +16 -0
  73. package/dist/components/booking-billing-dialog.d.ts.map +1 -0
  74. package/dist/components/booking-billing-dialog.js +315 -0
  75. package/dist/components/booking-cancellation-dialog.d.ts +18 -0
  76. package/dist/components/booking-cancellation-dialog.d.ts.map +1 -0
  77. package/dist/components/booking-cancellation-dialog.js +79 -0
  78. package/dist/components/booking-combobox.d.ts +13 -0
  79. package/dist/components/booking-combobox.d.ts.map +1 -0
  80. package/dist/components/booking-combobox.js +44 -0
  81. package/dist/components/booking-create-form-utils.d.ts +56 -0
  82. package/dist/components/booking-create-form-utils.d.ts.map +1 -0
  83. package/dist/components/booking-create-form-utils.js +216 -0
  84. package/dist/components/booking-create-page.d.ts +14 -0
  85. package/dist/components/booking-create-page.d.ts.map +1 -0
  86. package/dist/components/booking-create-page.js +11 -0
  87. package/dist/components/booking-create-preview-card.d.ts +26 -0
  88. package/dist/components/booking-create-preview-card.d.ts.map +1 -0
  89. package/dist/components/booking-create-preview-card.js +107 -0
  90. package/dist/components/booking-create-product-extras-picker.d.ts +18 -0
  91. package/dist/components/booking-create-product-extras-picker.d.ts.map +1 -0
  92. package/dist/components/booking-create-product-extras-picker.js +82 -0
  93. package/dist/components/booking-create-sheet.d.ts +34 -0
  94. package/dist/components/booking-create-sheet.d.ts.map +1 -0
  95. package/dist/components/booking-create-sheet.js +811 -0
  96. package/dist/components/booking-create-utils.d.ts +66 -0
  97. package/dist/components/booking-create-utils.d.ts.map +1 -0
  98. package/dist/components/booking-create-utils.js +185 -0
  99. package/dist/components/booking-detail-page.d.ts +126 -0
  100. package/dist/components/booking-detail-page.d.ts.map +1 -0
  101. package/dist/components/booking-detail-page.js +264 -0
  102. package/dist/components/booking-dialog.d.ts +28 -0
  103. package/dist/components/booking-dialog.d.ts.map +1 -0
  104. package/dist/components/booking-dialog.js +130 -0
  105. package/dist/components/booking-document-dialog.d.ts +8 -0
  106. package/dist/components/booking-document-dialog.d.ts.map +1 -0
  107. package/dist/components/booking-document-dialog.js +83 -0
  108. package/dist/components/booking-document-list.d.ts +5 -0
  109. package/dist/components/booking-document-list.d.ts.map +1 -0
  110. package/dist/components/booking-document-list.js +43 -0
  111. package/dist/components/booking-group-link-dialog.d.ts +10 -0
  112. package/dist/components/booking-group-link-dialog.d.ts.map +1 -0
  113. package/dist/components/booking-group-link-dialog.js +79 -0
  114. package/dist/components/booking-group-section.d.ts +27 -0
  115. package/dist/components/booking-group-section.d.ts.map +1 -0
  116. package/dist/components/booking-group-section.js +51 -0
  117. package/dist/components/booking-guarantee-dialog.d.ts +10 -0
  118. package/dist/components/booking-guarantee-dialog.d.ts.map +1 -0
  119. package/dist/components/booking-guarantee-dialog.js +123 -0
  120. package/dist/components/booking-guarantee-list.d.ts +5 -0
  121. package/dist/components/booking-guarantee-list.d.ts.map +1 -0
  122. package/dist/components/booking-guarantee-list.js +86 -0
  123. package/dist/components/booking-item-dialog.d.ts +10 -0
  124. package/dist/components/booking-item-dialog.d.ts.map +1 -0
  125. package/dist/components/booking-item-dialog.js +155 -0
  126. package/dist/components/booking-item-list.d.ts +12 -0
  127. package/dist/components/booking-item-list.d.ts.map +1 -0
  128. package/dist/components/booking-item-list.js +191 -0
  129. package/dist/components/booking-item-travelers.d.ts +6 -0
  130. package/dist/components/booking-item-travelers.d.ts.map +1 -0
  131. package/dist/components/booking-item-travelers.js +57 -0
  132. package/dist/components/booking-list-filters.d.ts +43 -0
  133. package/dist/components/booking-list-filters.d.ts.map +1 -0
  134. package/dist/components/booking-list-filters.js +192 -0
  135. package/dist/components/booking-list.d.ts +50 -0
  136. package/dist/components/booking-list.d.ts.map +1 -0
  137. package/dist/components/booking-list.js +352 -0
  138. package/dist/components/booking-note-dialog.d.ts +16 -0
  139. package/dist/components/booking-note-dialog.d.ts.map +1 -0
  140. package/dist/components/booking-note-dialog.js +41 -0
  141. package/dist/components/booking-notes.d.ts +5 -0
  142. package/dist/components/booking-notes.d.ts.map +1 -0
  143. package/dist/components/booking-notes.js +45 -0
  144. package/dist/components/booking-payment-reconciliation-banner.d.ts +5 -0
  145. package/dist/components/booking-payment-reconciliation-banner.d.ts.map +1 -0
  146. package/dist/components/booking-payment-reconciliation-banner.js +91 -0
  147. package/dist/components/booking-payment-schedule-dialog.d.ts +10 -0
  148. package/dist/components/booking-payment-schedule-dialog.d.ts.map +1 -0
  149. package/dist/components/booking-payment-schedule-dialog.js +117 -0
  150. package/dist/components/booking-payment-schedule-list.d.ts +10 -0
  151. package/dist/components/booking-payment-schedule-list.d.ts.map +1 -0
  152. package/dist/components/booking-payment-schedule-list.js +217 -0
  153. package/dist/components/booking-payments-summary.d.ts +83 -0
  154. package/dist/components/booking-payments-summary.d.ts.map +1 -0
  155. package/dist/components/booking-payments-summary.js +176 -0
  156. package/dist/components/booking-quick-view-sheet.d.ts +14 -0
  157. package/dist/components/booking-quick-view-sheet.d.ts.map +1 -0
  158. package/dist/components/booking-quick-view-sheet.js +283 -0
  159. package/dist/components/bookings-page.d.ts +19 -0
  160. package/dist/components/bookings-page.d.ts.map +1 -0
  161. package/dist/components/bookings-page.js +9 -0
  162. package/dist/components/file-dropzone.d.ts +25 -0
  163. package/dist/components/file-dropzone.d.ts.map +1 -0
  164. package/dist/components/file-dropzone.js +102 -0
  165. package/dist/components/icon-action-button.d.ts +18 -0
  166. package/dist/components/icon-action-button.d.ts.map +1 -0
  167. package/dist/components/icon-action-button.js +13 -0
  168. package/dist/components/option-units-stepper-section.d.ts +111 -0
  169. package/dist/components/option-units-stepper-section.d.ts.map +1 -0
  170. package/dist/components/option-units-stepper-section.js +276 -0
  171. package/dist/components/payment-schedule-section.d.ts +91 -0
  172. package/dist/components/payment-schedule-section.d.ts.map +1 -0
  173. package/dist/components/payment-schedule-section.js +206 -0
  174. package/dist/components/person-picker-section.d.ts +71 -0
  175. package/dist/components/person-picker-section.d.ts.map +1 -0
  176. package/dist/components/person-picker-section.js +160 -0
  177. package/dist/components/price-breakdown-section.d.ts +83 -0
  178. package/dist/components/price-breakdown-section.d.ts.map +1 -0
  179. package/dist/components/price-breakdown-section.js +278 -0
  180. package/dist/components/product-picker-section.d.ts +29 -0
  181. package/dist/components/product-picker-section.d.ts.map +1 -0
  182. package/dist/components/product-picker-section.js +74 -0
  183. package/dist/components/shared-room-section.d.ts +40 -0
  184. package/dist/components/shared-room-section.d.ts.map +1 -0
  185. package/dist/components/shared-room-section.js +99 -0
  186. package/dist/components/status-badge.d.ts +24 -0
  187. package/dist/components/status-badge.d.ts.map +1 -0
  188. package/dist/components/status-badge.js +65 -0
  189. package/dist/components/status-change-dialog.d.ts +10 -0
  190. package/dist/components/status-change-dialog.d.ts.map +1 -0
  191. package/dist/components/status-change-dialog.js +57 -0
  192. package/dist/components/supplier-status-dialog.d.ts +10 -0
  193. package/dist/components/supplier-status-dialog.d.ts.map +1 -0
  194. package/dist/components/supplier-status-dialog.js +98 -0
  195. package/dist/components/supplier-status-list.d.ts +5 -0
  196. package/dist/components/supplier-status-list.d.ts.map +1 -0
  197. package/dist/components/supplier-status-list.js +115 -0
  198. package/dist/components/traveler-category-buttons.d.ts +26 -0
  199. package/dist/components/traveler-category-buttons.d.ts.map +1 -0
  200. package/dist/components/traveler-category-buttons.js +35 -0
  201. package/dist/components/traveler-dialog.d.ts +10 -0
  202. package/dist/components/traveler-dialog.d.ts.map +1 -0
  203. package/dist/components/traveler-dialog.js +256 -0
  204. package/dist/components/traveler-list.d.ts +6 -0
  205. package/dist/components/traveler-list.d.ts.map +1 -0
  206. package/dist/components/traveler-list.js +295 -0
  207. package/dist/components/travelers-section-controls.d.ts +52 -0
  208. package/dist/components/travelers-section-controls.d.ts.map +1 -0
  209. package/dist/components/travelers-section-controls.js +206 -0
  210. package/dist/components/travelers-section.d.ts +159 -0
  211. package/dist/components/travelers-section.d.ts.map +1 -0
  212. package/dist/components/travelers-section.js +355 -0
  213. package/dist/components/voucher-picker-section.d.ts +50 -0
  214. package/dist/components/voucher-picker-section.d.ts.map +1 -0
  215. package/dist/components/voucher-picker-section.js +79 -0
  216. package/dist/extras/client.d.ts +14 -0
  217. package/dist/extras/client.d.ts.map +1 -0
  218. package/dist/extras/client.js +58 -0
  219. package/dist/extras/components/extra-catalog-card.d.ts +13 -0
  220. package/dist/extras/components/extra-catalog-card.d.ts.map +1 -0
  221. package/dist/extras/components/extra-catalog-card.js +52 -0
  222. package/dist/extras/components/product-combobox.d.ts +9 -0
  223. package/dist/extras/components/product-combobox.d.ts.map +1 -0
  224. package/dist/extras/components/product-combobox.js +46 -0
  225. package/dist/extras/components/slot-extras-manifest-panel.d.ts +6 -0
  226. package/dist/extras/components/slot-extras-manifest-panel.d.ts.map +1 -0
  227. package/dist/extras/components/slot-extras-manifest-panel.js +108 -0
  228. package/dist/extras/hooks/index.d.ts +5 -0
  229. package/dist/extras/hooks/index.d.ts.map +1 -0
  230. package/dist/extras/hooks/index.js +4 -0
  231. package/dist/extras/hooks/use-product-extra.d.ts +24 -0
  232. package/dist/extras/hooks/use-product-extra.d.ts.map +1 -0
  233. package/dist/extras/hooks/use-product-extra.js +12 -0
  234. package/dist/extras/hooks/use-product-extras.d.ts +30 -0
  235. package/dist/extras/hooks/use-product-extras.d.ts.map +1 -0
  236. package/dist/extras/hooks/use-product-extras.js +12 -0
  237. package/dist/extras/hooks/use-slot-extra-manifest-mutation.d.ts +48 -0
  238. package/dist/extras/hooks/use-slot-extra-manifest-mutation.d.ts.map +1 -0
  239. package/dist/extras/hooks/use-slot-extra-manifest-mutation.js +26 -0
  240. package/dist/extras/hooks/use-slot-extra-manifest.d.ts +68 -0
  241. package/dist/extras/hooks/use-slot-extra-manifest.d.ts.map +1 -0
  242. package/dist/extras/hooks/use-slot-extra-manifest.js +11 -0
  243. package/dist/extras/i18n/en.d.ts +52 -0
  244. package/dist/extras/i18n/en.d.ts.map +1 -0
  245. package/dist/extras/i18n/en.js +51 -0
  246. package/dist/extras/i18n/index.d.ts +5 -0
  247. package/dist/extras/i18n/index.d.ts.map +1 -0
  248. package/dist/extras/i18n/index.js +3 -0
  249. package/dist/extras/i18n/messages.d.ts +37 -0
  250. package/dist/extras/i18n/messages.d.ts.map +1 -0
  251. package/dist/extras/i18n/messages.js +1 -0
  252. package/dist/extras/i18n/provider.d.ts +126 -0
  253. package/dist/extras/i18n/provider.d.ts.map +1 -0
  254. package/dist/extras/i18n/provider.js +44 -0
  255. package/dist/extras/i18n/ro.d.ts +52 -0
  256. package/dist/extras/i18n/ro.d.ts.map +1 -0
  257. package/dist/extras/i18n/ro.js +51 -0
  258. package/dist/extras/index.d.ts +7 -0
  259. package/dist/extras/index.d.ts.map +1 -0
  260. package/dist/extras/index.js +6 -0
  261. package/dist/extras/provider.d.ts +2 -0
  262. package/dist/extras/provider.d.ts.map +1 -0
  263. package/dist/extras/provider.js +1 -0
  264. package/dist/extras/query-keys.d.ts +16 -0
  265. package/dist/extras/query-keys.d.ts.map +1 -0
  266. package/dist/extras/query-keys.js +8 -0
  267. package/dist/extras/query-options.d.ts +455 -0
  268. package/dist/extras/query-options.d.ts.map +1 -0
  269. package/dist/extras/query-options.js +44 -0
  270. package/dist/extras/schemas.d.ts +416 -0
  271. package/dist/extras/schemas.d.ts.map +1 -0
  272. package/dist/extras/schemas.js +89 -0
  273. package/dist/extras/ui.d.ts +4 -0
  274. package/dist/extras/ui.d.ts.map +1 -0
  275. package/dist/extras/ui.js +3 -0
  276. package/dist/extras.d.ts +10 -0
  277. package/dist/extras.d.ts.map +1 -0
  278. package/dist/extras.js +9 -0
  279. package/dist/hooks/index.d.ts +36 -0
  280. package/dist/hooks/index.d.ts.map +1 -0
  281. package/dist/hooks/index.js +35 -0
  282. package/dist/hooks/use-booking-action-ledger.d.ts +63 -0
  283. package/dist/hooks/use-booking-action-ledger.d.ts.map +1 -0
  284. package/dist/hooks/use-booking-action-ledger.js +34 -0
  285. package/dist/hooks/use-booking-activity.d.ts +17 -0
  286. package/dist/hooks/use-booking-activity.d.ts.map +1 -0
  287. package/dist/hooks/use-booking-activity.js +12 -0
  288. package/dist/hooks/use-booking-cancel-mutation.d.ts +69 -0
  289. package/dist/hooks/use-booking-cancel-mutation.d.ts.map +1 -0
  290. package/dist/hooks/use-booking-cancel-mutation.js +24 -0
  291. package/dist/hooks/use-booking-contract-generation.d.ts +31 -0
  292. package/dist/hooks/use-booking-contract-generation.d.ts.map +1 -0
  293. package/dist/hooks/use-booking-contract-generation.js +36 -0
  294. package/dist/hooks/use-booking-convert-mutation.d.ts +81 -0
  295. package/dist/hooks/use-booking-convert-mutation.d.ts.map +1 -0
  296. package/dist/hooks/use-booking-convert-mutation.js +24 -0
  297. package/dist/hooks/use-booking-create-mutation.d.ts +337 -0
  298. package/dist/hooks/use-booking-create-mutation.d.ts.map +1 -0
  299. package/dist/hooks/use-booking-create-mutation.js +43 -0
  300. package/dist/hooks/use-booking-documents.d.ts +41 -0
  301. package/dist/hooks/use-booking-documents.d.ts.map +1 -0
  302. package/dist/hooks/use-booking-documents.js +46 -0
  303. package/dist/hooks/use-booking-dual-create-mutation.d.ts +338 -0
  304. package/dist/hooks/use-booking-dual-create-mutation.d.ts.map +1 -0
  305. package/dist/hooks/use-booking-dual-create-mutation.js +45 -0
  306. package/dist/hooks/use-booking-group-for-booking.d.ts +24 -0
  307. package/dist/hooks/use-booking-group-for-booking.d.ts.map +1 -0
  308. package/dist/hooks/use-booking-group-for-booking.js +12 -0
  309. package/dist/hooks/use-booking-group-member-mutation.d.ts +27 -0
  310. package/dist/hooks/use-booking-group-member-mutation.d.ts.map +1 -0
  311. package/dist/hooks/use-booking-group-member-mutation.js +38 -0
  312. package/dist/hooks/use-booking-group-mutation.d.ts +40 -0
  313. package/dist/hooks/use-booking-group-mutation.d.ts.map +1 -0
  314. package/dist/hooks/use-booking-group-mutation.js +32 -0
  315. package/dist/hooks/use-booking-group.d.ts +85 -0
  316. package/dist/hooks/use-booking-group.d.ts.map +1 -0
  317. package/dist/hooks/use-booking-group.js +12 -0
  318. package/dist/hooks/use-booking-groups.d.ts +21 -0
  319. package/dist/hooks/use-booking-groups.d.ts.map +1 -0
  320. package/dist/hooks/use-booking-groups.js +12 -0
  321. package/dist/hooks/use-booking-item-mutation.d.ts +101 -0
  322. package/dist/hooks/use-booking-item-mutation.d.ts.map +1 -0
  323. package/dist/hooks/use-booking-item-mutation.js +42 -0
  324. package/dist/hooks/use-booking-item-travelers.d.ts +32 -0
  325. package/dist/hooks/use-booking-item-travelers.d.ts.map +1 -0
  326. package/dist/hooks/use-booking-item-travelers.js +48 -0
  327. package/dist/hooks/use-booking-items.d.ts +36 -0
  328. package/dist/hooks/use-booking-items.d.ts.map +1 -0
  329. package/dist/hooks/use-booking-items.js +12 -0
  330. package/dist/hooks/use-booking-mutation.d.ts +158 -0
  331. package/dist/hooks/use-booking-mutation.d.ts.map +1 -0
  332. package/dist/hooks/use-booking-mutation.js +39 -0
  333. package/dist/hooks/use-booking-note-mutation.d.ts +39 -0
  334. package/dist/hooks/use-booking-note-mutation.d.ts.map +1 -0
  335. package/dist/hooks/use-booking-note-mutation.js +44 -0
  336. package/dist/hooks/use-booking-notes.d.ts +15 -0
  337. package/dist/hooks/use-booking-notes.d.ts.map +1 -0
  338. package/dist/hooks/use-booking-notes.js +12 -0
  339. package/dist/hooks/use-booking-primary-product.d.ts +28 -0
  340. package/dist/hooks/use-booking-primary-product.d.ts.map +1 -0
  341. package/dist/hooks/use-booking-primary-product.js +20 -0
  342. package/dist/hooks/use-booking-status-mutation.d.ts +156 -0
  343. package/dist/hooks/use-booking-status-mutation.d.ts.map +1 -0
  344. package/dist/hooks/use-booking-status-mutation.js +54 -0
  345. package/dist/hooks/use-booking-tax-preview.d.ts +29 -0
  346. package/dist/hooks/use-booking-tax-preview.d.ts.map +1 -0
  347. package/dist/hooks/use-booking-tax-preview.js +21 -0
  348. package/dist/hooks/use-booking.d.ts +67 -0
  349. package/dist/hooks/use-booking.d.ts.map +1 -0
  350. package/dist/hooks/use-booking.js +12 -0
  351. package/dist/hooks/use-bookings.d.ts +71 -0
  352. package/dist/hooks/use-bookings.d.ts.map +1 -0
  353. package/dist/hooks/use-bookings.js +12 -0
  354. package/dist/hooks/use-pricing-preview.d.ts +61 -0
  355. package/dist/hooks/use-pricing-preview.d.ts.map +1 -0
  356. package/dist/hooks/use-pricing-preview.js +18 -0
  357. package/dist/hooks/use-public-booking-session-flow-mutation.d.ts +148 -0
  358. package/dist/hooks/use-public-booking-session-flow-mutation.d.ts.map +1 -0
  359. package/dist/hooks/use-public-booking-session-flow-mutation.js +35 -0
  360. package/dist/hooks/use-public-booking-session-state.d.ts +16 -0
  361. package/dist/hooks/use-public-booking-session-state.d.ts.map +1 -0
  362. package/dist/hooks/use-public-booking-session-state.js +12 -0
  363. package/dist/hooks/use-public-booking-session.d.ts +101 -0
  364. package/dist/hooks/use-public-booking-session.d.ts.map +1 -0
  365. package/dist/hooks/use-public-booking-session.js +12 -0
  366. package/dist/hooks/use-reveal-traveler.d.ts +54 -0
  367. package/dist/hooks/use-reveal-traveler.d.ts.map +1 -0
  368. package/dist/hooks/use-reveal-traveler.js +18 -0
  369. package/dist/hooks/use-sharing-groups.d.ts +41 -0
  370. package/dist/hooks/use-sharing-groups.d.ts.map +1 -0
  371. package/dist/hooks/use-sharing-groups.js +20 -0
  372. package/dist/hooks/use-supplier-status-mutation.d.ts +46 -0
  373. package/dist/hooks/use-supplier-status-mutation.d.ts.map +1 -0
  374. package/dist/hooks/use-supplier-status-mutation.js +39 -0
  375. package/dist/hooks/use-supplier-statuses.d.ts +20 -0
  376. package/dist/hooks/use-supplier-statuses.d.ts.map +1 -0
  377. package/dist/hooks/use-supplier-statuses.js +12 -0
  378. package/dist/hooks/use-traveler-mutation.d.ts +55 -0
  379. package/dist/hooks/use-traveler-mutation.d.ts.map +1 -0
  380. package/dist/hooks/use-traveler-mutation.js +42 -0
  381. package/dist/hooks/use-traveler-with-travel-details-mutation.d.ts +120 -0
  382. package/dist/hooks/use-traveler-with-travel-details-mutation.d.ts.map +1 -0
  383. package/dist/hooks/use-traveler-with-travel-details-mutation.js +43 -0
  384. package/dist/hooks/use-travelers.d.ts +23 -0
  385. package/dist/hooks/use-travelers.d.ts.map +1 -0
  386. package/dist/hooks/use-travelers.js +12 -0
  387. package/dist/i18n/en-base.d.ts +295 -0
  388. package/dist/i18n/en-base.d.ts.map +1 -0
  389. package/dist/i18n/en-base.js +294 -0
  390. package/dist/i18n/en-create-list.d.ts +327 -0
  391. package/dist/i18n/en-create-list.d.ts.map +1 -0
  392. package/dist/i18n/en-create-list.js +326 -0
  393. package/dist/i18n/en-journey.d.ts +229 -0
  394. package/dist/i18n/en-journey.d.ts.map +1 -0
  395. package/dist/i18n/en-journey.js +228 -0
  396. package/dist/i18n/en-operations.d.ts +382 -0
  397. package/dist/i18n/en-operations.d.ts.map +1 -0
  398. package/dist/i18n/en-operations.js +381 -0
  399. package/dist/i18n/en-sections.d.ts +360 -0
  400. package/dist/i18n/en-sections.d.ts.map +1 -0
  401. package/dist/i18n/en-sections.js +359 -0
  402. package/dist/i18n/en.d.ts +1581 -0
  403. package/dist/i18n/en.d.ts.map +1 -0
  404. package/dist/i18n/en.js +12 -0
  405. package/dist/i18n/index.d.ts +5 -0
  406. package/dist/i18n/index.d.ts.map +1 -0
  407. package/dist/i18n/index.js +3 -0
  408. package/dist/i18n/messages-base.d.ts +251 -0
  409. package/dist/i18n/messages-base.d.ts.map +1 -0
  410. package/dist/i18n/messages-base.js +1 -0
  411. package/dist/i18n/messages-create-list.d.ts +310 -0
  412. package/dist/i18n/messages-create-list.d.ts.map +1 -0
  413. package/dist/i18n/messages-create-list.js +1 -0
  414. package/dist/i18n/messages-journey.d.ts +198 -0
  415. package/dist/i18n/messages-journey.d.ts.map +1 -0
  416. package/dist/i18n/messages-journey.js +1 -0
  417. package/dist/i18n/messages-operations.d.ts +362 -0
  418. package/dist/i18n/messages-operations.d.ts.map +1 -0
  419. package/dist/i18n/messages-operations.js +1 -0
  420. package/dist/i18n/messages-sections.d.ts +312 -0
  421. package/dist/i18n/messages-sections.d.ts.map +1 -0
  422. package/dist/i18n/messages-sections.js +1 -0
  423. package/dist/i18n/messages.d.ts +7 -0
  424. package/dist/i18n/messages.d.ts.map +1 -0
  425. package/dist/i18n/messages.js +1 -0
  426. package/dist/i18n/provider.d.ts +3185 -0
  427. package/dist/i18n/provider.d.ts.map +1 -0
  428. package/dist/i18n/provider.js +45 -0
  429. package/dist/i18n/ro-base.d.ts +295 -0
  430. package/dist/i18n/ro-base.d.ts.map +1 -0
  431. package/dist/i18n/ro-base.js +294 -0
  432. package/dist/i18n/ro-create-list.d.ts +327 -0
  433. package/dist/i18n/ro-create-list.d.ts.map +1 -0
  434. package/dist/i18n/ro-create-list.js +326 -0
  435. package/dist/i18n/ro-journey.d.ts +229 -0
  436. package/dist/i18n/ro-journey.d.ts.map +1 -0
  437. package/dist/i18n/ro-journey.js +228 -0
  438. package/dist/i18n/ro-operations.d.ts +382 -0
  439. package/dist/i18n/ro-operations.d.ts.map +1 -0
  440. package/dist/i18n/ro-operations.js +381 -0
  441. package/dist/i18n/ro-sections.d.ts +360 -0
  442. package/dist/i18n/ro-sections.d.ts.map +1 -0
  443. package/dist/i18n/ro-sections.js +359 -0
  444. package/dist/i18n/ro.d.ts +1581 -0
  445. package/dist/i18n/ro.d.ts.map +1 -0
  446. package/dist/i18n/ro.js +12 -0
  447. package/dist/index.d.ts +9 -0
  448. package/dist/index.d.ts.map +1 -0
  449. package/dist/index.js +8 -0
  450. package/dist/journey/components/booking-journey-rules.d.ts +48 -0
  451. package/dist/journey/components/booking-journey-rules.d.ts.map +1 -0
  452. package/dist/journey/components/booking-journey-rules.js +235 -0
  453. package/dist/journey/components/booking-journey.d.ts +3 -0
  454. package/dist/journey/components/booking-journey.d.ts.map +1 -0
  455. package/dist/journey/components/booking-journey.js +368 -0
  456. package/dist/journey/components/configure-step-skeleton.d.ts +8 -0
  457. package/dist/journey/components/configure-step-skeleton.d.ts.map +1 -0
  458. package/dist/journey/components/configure-step-skeleton.js +11 -0
  459. package/dist/journey/components/contract-preview-dialog.d.ts +47 -0
  460. package/dist/journey/components/contract-preview-dialog.d.ts.map +1 -0
  461. package/dist/journey/components/contract-preview-dialog.js +124 -0
  462. package/dist/journey/components/journey-steps/accommodation-step.d.ts +3 -0
  463. package/dist/journey/components/journey-steps/accommodation-step.d.ts.map +1 -0
  464. package/dist/journey/components/journey-steps/accommodation-step.js +71 -0
  465. package/dist/journey/components/journey-steps/addons-step.d.ts +3 -0
  466. package/dist/journey/components/journey-steps/addons-step.d.ts.map +1 -0
  467. package/dist/journey/components/journey-steps/addons-step.js +40 -0
  468. package/dist/journey/components/journey-steps/billing-step.d.ts +8 -0
  469. package/dist/journey/components/journey-steps/billing-step.d.ts.map +1 -0
  470. package/dist/journey/components/journey-steps/billing-step.js +78 -0
  471. package/dist/journey/components/journey-steps/configure-steps.d.ts +28 -0
  472. package/dist/journey/components/journey-steps/configure-steps.d.ts.map +1 -0
  473. package/dist/journey/components/journey-steps/configure-steps.js +232 -0
  474. package/dist/journey/components/journey-steps/documents-step.d.ts +11 -0
  475. package/dist/journey/components/journey-steps/documents-step.d.ts.map +1 -0
  476. package/dist/journey/components/journey-steps/documents-step.js +36 -0
  477. package/dist/journey/components/journey-steps/payment-step.d.ts +29 -0
  478. package/dist/journey/components/journey-steps/payment-step.d.ts.map +1 -0
  479. package/dist/journey/components/journey-steps/payment-step.js +225 -0
  480. package/dist/journey/components/journey-steps/review-step.d.ts +27 -0
  481. package/dist/journey/components/journey-steps/review-step.d.ts.map +1 -0
  482. package/dist/journey/components/journey-steps/review-step.js +18 -0
  483. package/dist/journey/components/journey-steps/shared.d.ts +75 -0
  484. package/dist/journey/components/journey-steps/shared.d.ts.map +1 -0
  485. package/dist/journey/components/journey-steps/shared.js +108 -0
  486. package/dist/journey/components/journey-steps/travelers-step.d.ts +7 -0
  487. package/dist/journey/components/journey-steps/travelers-step.d.ts.map +1 -0
  488. package/dist/journey/components/journey-steps/travelers-step.js +201 -0
  489. package/dist/journey/components/journey-steps.d.ts +21 -0
  490. package/dist/journey/components/journey-steps.d.ts.map +1 -0
  491. package/dist/journey/components/journey-steps.js +20 -0
  492. package/dist/journey/components/side-panel.d.ts +17 -0
  493. package/dist/journey/components/side-panel.d.ts.map +1 -0
  494. package/dist/journey/components/side-panel.js +245 -0
  495. package/dist/journey/components/stacked-journey.d.ts +30 -0
  496. package/dist/journey/components/stacked-journey.d.ts.map +1 -0
  497. package/dist/journey/components/stacked-journey.js +50 -0
  498. package/dist/journey/components/step-header.d.ts +7 -0
  499. package/dist/journey/components/step-header.d.ts.map +1 -0
  500. package/dist/journey/components/step-header.js +12 -0
  501. package/dist/journey/index.d.ts +18 -0
  502. package/dist/journey/index.d.ts.map +1 -0
  503. package/dist/journey/index.js +17 -0
  504. package/dist/journey/lib/draft-state.d.ts +35 -0
  505. package/dist/journey/lib/draft-state.d.ts.map +1 -0
  506. package/dist/journey/lib/draft-state.js +57 -0
  507. package/dist/journey/lib/pax-band-dependencies.d.ts +27 -0
  508. package/dist/journey/lib/pax-band-dependencies.d.ts.map +1 -0
  509. package/dist/journey/lib/pax-band-dependencies.js +50 -0
  510. package/dist/journey/lib/payment-schedule.d.ts +19 -0
  511. package/dist/journey/lib/payment-schedule.d.ts.map +1 -0
  512. package/dist/journey/lib/payment-schedule.js +90 -0
  513. package/dist/journey/types.d.ts +403 -0
  514. package/dist/journey/types.d.ts.map +1 -0
  515. package/dist/journey/types.js +19 -0
  516. package/dist/provider.d.ts +2 -0
  517. package/dist/provider.d.ts.map +1 -0
  518. package/dist/provider.js +1 -0
  519. package/dist/query-keys.d.ts +74 -0
  520. package/dist/query-keys.d.ts.map +1 -0
  521. package/dist/query-keys.js +26 -0
  522. package/dist/query-options.d.ts +2534 -0
  523. package/dist/query-options.d.ts.map +1 -0
  524. package/dist/query-options.js +233 -0
  525. package/dist/requirements/client.d.ts +14 -0
  526. package/dist/requirements/client.d.ts.map +1 -0
  527. package/dist/requirements/client.js +59 -0
  528. package/dist/requirements/components/booking-requirements-contact-tab.d.ts +8 -0
  529. package/dist/requirements/components/booking-requirements-contact-tab.d.ts.map +1 -0
  530. package/dist/requirements/components/booking-requirements-contact-tab.js +8 -0
  531. package/dist/requirements/components/booking-requirements-questions-tab.d.ts +14 -0
  532. package/dist/requirements/components/booking-requirements-questions-tab.d.ts.map +1 -0
  533. package/dist/requirements/components/booking-requirements-questions-tab.js +17 -0
  534. package/dist/requirements/constants.d.ts +114 -0
  535. package/dist/requirements/constants.d.ts.map +1 -0
  536. package/dist/requirements/constants.js +45 -0
  537. package/dist/requirements/hooks/index.d.ts +6 -0
  538. package/dist/requirements/hooks/index.d.ts.map +1 -0
  539. package/dist/requirements/hooks/index.js +6 -0
  540. package/dist/requirements/hooks/use-booking-questions.d.ts +24 -0
  541. package/dist/requirements/hooks/use-booking-questions.d.ts.map +1 -0
  542. package/dist/requirements/hooks/use-booking-questions.js +9 -0
  543. package/dist/requirements/hooks/use-contact-requirements.d.ts +22 -0
  544. package/dist/requirements/hooks/use-contact-requirements.d.ts.map +1 -0
  545. package/dist/requirements/hooks/use-contact-requirements.js +9 -0
  546. package/dist/requirements/hooks/use-products.d.ts +16 -0
  547. package/dist/requirements/hooks/use-products.d.ts.map +1 -0
  548. package/dist/requirements/hooks/use-products.js +9 -0
  549. package/dist/requirements/hooks/use-question-options.d.ts +19 -0
  550. package/dist/requirements/hooks/use-question-options.d.ts.map +1 -0
  551. package/dist/requirements/hooks/use-question-options.js +9 -0
  552. package/dist/requirements/hooks/use-transport-requirements.d.ts +30 -0
  553. package/dist/requirements/hooks/use-transport-requirements.d.ts.map +1 -0
  554. package/dist/requirements/hooks/use-transport-requirements.js +9 -0
  555. package/dist/requirements/i18n/en.d.ts +94 -0
  556. package/dist/requirements/i18n/en.d.ts.map +1 -0
  557. package/dist/requirements/i18n/en.js +93 -0
  558. package/dist/requirements/i18n/index.d.ts +5 -0
  559. package/dist/requirements/i18n/index.d.ts.map +1 -0
  560. package/dist/requirements/i18n/index.js +3 -0
  561. package/dist/requirements/i18n/messages.d.ts +59 -0
  562. package/dist/requirements/i18n/messages.d.ts.map +1 -0
  563. package/dist/requirements/i18n/messages.js +1 -0
  564. package/dist/requirements/i18n/provider.d.ts +210 -0
  565. package/dist/requirements/i18n/provider.d.ts.map +1 -0
  566. package/dist/requirements/i18n/provider.js +44 -0
  567. package/dist/requirements/i18n/ro.d.ts +94 -0
  568. package/dist/requirements/i18n/ro.d.ts.map +1 -0
  569. package/dist/requirements/i18n/ro.js +93 -0
  570. package/dist/requirements/index.d.ts +9 -0
  571. package/dist/requirements/index.d.ts.map +1 -0
  572. package/dist/requirements/index.js +8 -0
  573. package/dist/requirements/provider.d.ts +2 -0
  574. package/dist/requirements/provider.d.ts.map +1 -0
  575. package/dist/requirements/provider.js +1 -0
  576. package/dist/requirements/query-keys.d.ts +33 -0
  577. package/dist/requirements/query-keys.d.ts.map +1 -0
  578. package/dist/requirements/query-keys.js +13 -0
  579. package/dist/requirements/query-options.d.ts +371 -0
  580. package/dist/requirements/query-options.d.ts.map +1 -0
  581. package/dist/requirements/query-options.js +80 -0
  582. package/dist/requirements/schemas.d.ts +320 -0
  583. package/dist/requirements/schemas.d.ts.map +1 -0
  584. package/dist/requirements/schemas.js +121 -0
  585. package/dist/requirements/ui.d.ts +4 -0
  586. package/dist/requirements/ui.d.ts.map +1 -0
  587. package/dist/requirements/ui.js +3 -0
  588. package/dist/requirements/utils.d.ts +2 -0
  589. package/dist/requirements/utils.d.ts.map +1 -0
  590. package/dist/requirements/utils.js +4 -0
  591. package/dist/schemas.d.ts +2070 -0
  592. package/dist/schemas.d.ts.map +1 -0
  593. package/dist/schemas.js +507 -0
  594. package/dist/status-presentation.d.ts +34 -0
  595. package/dist/status-presentation.d.ts.map +1 -0
  596. package/dist/status-presentation.js +38 -0
  597. package/dist/ui.d.ts +43 -0
  598. package/dist/ui.d.ts.map +1 -0
  599. package/dist/ui.js +42 -0
  600. package/package.json +256 -0
  601. package/src/requirements/styles.css +1 -0
  602. package/src/styles.css +13 -0
@@ -0,0 +1,355 @@
1
+ // agent-quality: file-size exception -- owner: bookings-react; existing UI surface stays co-located until a dedicated split preserves behavior and tests.
2
+ "use client";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import { usePerson, usePersonRelationships, } from "@voyant-travel/relationships-react";
5
+ import { Button, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@voyant-travel/ui/components";
6
+ import { Trash2, UserPlus } from "lucide-react";
7
+ import * as React from "react";
8
+ import { useBookingsUiMessagesOrDefault } from "../i18n/provider.js";
9
+ import { createTravelerFromPerson, RelatedPersonChip, TravelerCategoryButtons, TravelerPersonPicker, TravelerPricingCategorySelect, } from "./travelers-section-controls.js";
10
+ export const emptyTravelerListValue = { travelers: [] };
11
+ function createClientTravelerKey() {
12
+ const random = typeof globalThis.crypto?.randomUUID === "function"
13
+ ? globalThis.crypto.randomUUID().replace(/-/g, "")
14
+ : `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
15
+ return `trav:${random}`;
16
+ }
17
+ /** Factory for a blank row — `role` defaults to `adult` unless the list is empty. */
18
+ export function createBlankTraveler(role = "adult") {
19
+ return {
20
+ clientTravelerKey: createClientTravelerKey(),
21
+ personId: null,
22
+ firstName: "",
23
+ lastName: "",
24
+ email: "",
25
+ phone: "",
26
+ preferredLanguage: "",
27
+ role,
28
+ dateOfBirth: null,
29
+ pricingUnitId: null,
30
+ pricingCategoryId: null,
31
+ inventoryUnitId: null,
32
+ pricingUnitSource: "auto",
33
+ inventoryUnitSource: "auto",
34
+ };
35
+ }
36
+ // Re-export `computeAgeYears` from the canonical assignment module so
37
+ // existing consumers of `travelers-section`'s public surface keep
38
+ // working. The implementation lives in `@voyant-travel/bookings/pricing-assignment`.
39
+ export { computeAgeYears } from "@voyant-travel/bookings/pricing-assignment";
40
+ import { computeAgeYears as _computeAgeYears, matchUnitByDob as matchAssignmentUnitByDob, matchUnitByRoleHint as matchAssignmentUnitByRoleHint, } from "@voyant-travel/bookings/pricing-assignment";
41
+ /**
42
+ * Derive the age-banded traveler role from DOB. Falls back to `adult`
43
+ * when DOB is missing so partial entries still typecheck downstream.
44
+ *
45
+ * Thresholds:
46
+ * - infant: < 2
47
+ * - child: 2 – 17
48
+ * - adult: 18+
49
+ */
50
+ export function deriveTravelerRoleFromDob(dob) {
51
+ const age = _computeAgeYears(dob);
52
+ if (age == null)
53
+ return "adult";
54
+ if (age < 2)
55
+ return "infant";
56
+ if (age < 18)
57
+ return "child";
58
+ return "adult";
59
+ }
60
+ function roleFromPricingCategoryType(categoryType) {
61
+ if (categoryType === "child")
62
+ return "child";
63
+ if (categoryType === "infant")
64
+ return "infant";
65
+ return "adult";
66
+ }
67
+ export function categoryMatchesDob(category, dob) {
68
+ if (category.minAge == null && category.maxAge == null)
69
+ return false;
70
+ const age = _computeAgeYears(dob);
71
+ if (age == null)
72
+ return false;
73
+ return ((category.minAge == null || age >= category.minAge) &&
74
+ (category.maxAge == null || age <= category.maxAge));
75
+ }
76
+ function categoryMatchesRole(category, role) {
77
+ if (role === "lead" || role === "adult")
78
+ return category.categoryType === "adult";
79
+ if (role === "child")
80
+ return category.categoryType === "child";
81
+ if (role === "infant")
82
+ return category.categoryType === "infant";
83
+ return false;
84
+ }
85
+ export function matchPricingCategoryForTraveler(categories, dob, role, inventoryUnitId) {
86
+ if (!categories || categories.length === 0)
87
+ return null;
88
+ const pool = inventoryUnitId
89
+ ? categories.filter((category) => category.unitIds.includes(inventoryUnitId))
90
+ : categories;
91
+ if (pool.length === 0)
92
+ return null;
93
+ return (pool.find((category) => categoryMatchesDob(category, dob))?.categoryId ??
94
+ pool.find((category) => categoryMatchesRole(category, role))?.categoryId ??
95
+ pool[0]?.categoryId ??
96
+ null);
97
+ }
98
+ /**
99
+ * Adapter from this file's `RoomGroupUnit` shape (UI-side, uses
100
+ * `unitId`) to the canonical `PricingAssignmentUnit` shape (uses
101
+ * `optionUnitId`). Phase 1 of voyant-travel/voyant#1267 will collapse these
102
+ * by renaming the UI shape.
103
+ */
104
+ function roomGroupUnitsAsAssignmentUnits(units) {
105
+ return units.map((u) => ({
106
+ optionId: null,
107
+ optionUnitId: u.unitId,
108
+ unitName: u.unitName,
109
+ unitCode: u.unitCode,
110
+ minAge: u.minAge,
111
+ maxAge: u.maxAge,
112
+ unitType: u.unitType,
113
+ }));
114
+ }
115
+ function matchUnitByDob(units, dob) {
116
+ return matchAssignmentUnitByDob(roomGroupUnitsAsAssignmentUnits(units), dob);
117
+ }
118
+ function matchUnitByRoleHint(units, role) {
119
+ return matchAssignmentUnitByRoleHint(roomGroupUnitsAsAssignmentUnits(units), role);
120
+ }
121
+ const NO_ROOM = "__unassigned__";
122
+ /**
123
+ * Traveler list for booking-create flows. Each row can point at an existing
124
+ * CRM person, create a new CRM person, or carry manual name/email details,
125
+ * plus role and optional room assignment.
126
+ *
127
+ * ### Parent contract
128
+ *
129
+ * At submit time, the parent:
130
+ * 1. Inserts a `booking_travelers` row per traveler with `participantType`
131
+ * derived from the role (`lead` / `adult` → traveler; `child` / `infant`
132
+ * → traveler with travelerCategory set).
133
+ * 2. Carries `personId` through when the traveler is tied to CRM, including
134
+ * when the payer is also traveling.
135
+ * 3. Exactly one row should have `role: "lead"` — enforced at submit, not
136
+ * here. The UI lets the operator pick whichever layout they want, then
137
+ * the submit handler errors if the invariant isn't met.
138
+ */
139
+ export function TravelersSection({ value, onChange, roomUnits, roomGroups, pricingCategories, billingPersonId, labels, }) {
140
+ const messages = useBookingsUiMessagesOrDefault();
141
+ const merged = { ...messages.travelersSection.labels, ...labels };
142
+ const billingPerson = usePerson(billingPersonId ?? undefined, {
143
+ enabled: Boolean(billingPersonId),
144
+ });
145
+ const updateAt = (index, patch) => {
146
+ const next = value.travelers.map((traveler, i) => i === index ? { ...traveler, ...patch } : traveler);
147
+ onChange({ travelers: next });
148
+ };
149
+ const removeAt = (index) => {
150
+ onChange({ travelers: value.travelers.filter((_, i) => i !== index) });
151
+ };
152
+ const pickPricingUnitIdForTraveler = React.useCallback((dateOfBirth = null, role = null, preferredUnitId = null) => {
153
+ if (!roomGroups || roomGroups.length === 0)
154
+ return null;
155
+ const group = (preferredUnitId
156
+ ? roomGroups.find((g) => g.primaryUnitId === preferredUnitId ||
157
+ g.units.some((u) => u.unitId === preferredUnitId))
158
+ : undefined) ?? roomGroups[0];
159
+ if (!group)
160
+ return null;
161
+ return (matchUnitByDob(group.units, dateOfBirth) ??
162
+ matchUnitByRoleHint(group.units, role) ??
163
+ group.units.find((unit) => unit.unitType == null || unit.unitType === "person")?.unitId ??
164
+ null);
165
+ }, [roomGroups]);
166
+ // Auto-pick a room with seats available so operators don't have to
167
+ // hunt for the dropdown on every traveler — they can still override
168
+ // manually via the Room select. Pricing is picked from the same
169
+ // option when the product exposes person tiers.
170
+ const pickAssignmentsForNewTraveler = React.useCallback((dateOfBirth = null, role = null) => {
171
+ if (!roomUnits || roomUnits.length === 0) {
172
+ return {
173
+ pricingUnitId: null,
174
+ pricingCategoryId: matchPricingCategoryForTraveler(pricingCategories, dateOfBirth, role, null),
175
+ inventoryUnitId: null,
176
+ };
177
+ }
178
+ const pickedRoom = roomUnits.find((unit) => unit.remainingCapacity > 0)?.unitId ?? null;
179
+ if (!pickedRoom || !roomGroups || roomGroups.length === 0) {
180
+ return {
181
+ pricingUnitId: null,
182
+ pricingCategoryId: matchPricingCategoryForTraveler(pricingCategories, dateOfBirth, role, pickedRoom),
183
+ inventoryUnitId: pickedRoom,
184
+ };
185
+ }
186
+ const pricingUnitId = pickPricingUnitIdForTraveler(dateOfBirth, role, pickedRoom);
187
+ return {
188
+ pricingUnitId,
189
+ pricingCategoryId: matchPricingCategoryForTraveler(pricingCategories, dateOfBirth, role, pickedRoom),
190
+ inventoryUnitId: pickedRoom,
191
+ };
192
+ }, [roomUnits, roomGroups, pricingCategories, pickPricingUnitIdForTraveler]);
193
+ // Note: there is no hydration effect any more. Travelers attached
194
+ // before the option-units queries resolve get null assignment ids
195
+ // and `*UnitSource: "auto"`; the resolver in
196
+ // `@voyant-travel/bookings/pricing-assignment` re-derives them at every
197
+ // preview/submit pass, and respects `"none"` (explicit No room) /
198
+ // `"manual"` (operator click) when set. Operator intent is now
199
+ // declarative on the row, not implicit in a one-shot effect.
200
+ const addRow = () => {
201
+ // First traveler defaults to `lead` so the operator doesn't have to
202
+ // remember to flip the role on the initial row.
203
+ const role = value.travelers.length === 0 ? "lead" : "adult";
204
+ const blank = createBlankTraveler(role);
205
+ onChange({
206
+ travelers: [
207
+ ...value.travelers,
208
+ {
209
+ ...blank,
210
+ ...pickAssignmentsForNewTraveler(null, role),
211
+ pricingUnitSource: "auto",
212
+ inventoryUnitSource: "auto",
213
+ },
214
+ ],
215
+ });
216
+ };
217
+ const addBillingPerson = () => {
218
+ if (!billingPerson.data)
219
+ return;
220
+ const role = value.travelers.length === 0 ? "lead" : "adult";
221
+ const traveler = createTravelerFromPerson(billingPerson.data, role);
222
+ onChange({
223
+ travelers: [
224
+ ...value.travelers,
225
+ {
226
+ ...traveler,
227
+ ...pickAssignmentsForNewTraveler(traveler.dateOfBirth, role),
228
+ pricingUnitSource: "auto",
229
+ inventoryUnitSource: "auto",
230
+ },
231
+ ],
232
+ });
233
+ };
234
+ const addRelatedPersonTraveler = (person) => {
235
+ const role = value.travelers.length === 0 ? "lead" : "adult";
236
+ const traveler = createTravelerFromPerson(person, role);
237
+ onChange({
238
+ travelers: [
239
+ ...value.travelers,
240
+ {
241
+ ...traveler,
242
+ ...pickAssignmentsForNewTraveler(traveler.dateOfBirth, role),
243
+ pricingUnitSource: "auto",
244
+ inventoryUnitSource: "auto",
245
+ },
246
+ ],
247
+ });
248
+ };
249
+ const hasBillingPersonTraveler = Boolean(billingPersonId && value.travelers.some((traveler) => traveler.personId === billingPersonId));
250
+ // Relationships of the billing person — surfaced as one-click "add as
251
+ // traveler" chips so the operator can populate family/companions
252
+ // without searching for them in the picker.
253
+ const relationshipsQuery = usePersonRelationships(billingPersonId ?? undefined, {
254
+ enabled: Boolean(billingPersonId),
255
+ });
256
+ const alreadyAddedIds = React.useMemo(() => new Set(value.travelers.map((t) => t.personId).filter(Boolean)), [value.travelers]);
257
+ const relatedPersonIds = React.useMemo(() => {
258
+ if (!billingPersonId)
259
+ return [];
260
+ const seen = new Set();
261
+ const out = [];
262
+ for (const rel of relationshipsQuery.data?.data ?? []) {
263
+ const otherId = rel.fromPersonId === billingPersonId ? rel.toPersonId : rel.fromPersonId;
264
+ if (seen.has(otherId) || alreadyAddedIds.has(otherId))
265
+ continue;
266
+ seen.add(otherId);
267
+ out.push({ id: otherId, kind: rel.kind });
268
+ }
269
+ return out;
270
+ }, [billingPersonId, relationshipsQuery.data?.data, alreadyAddedIds]);
271
+ // base-ui's Select reads labels via the `items` prop — without it,
272
+ // <SelectValue /> falls back to the raw value (the unit id). Memoize
273
+ // once for all rows so identity is stable across renders.
274
+ const roomSelectItems = React.useMemo(() => [
275
+ { label: merged.noRoom, value: NO_ROOM },
276
+ ...(roomUnits ?? []).map((unit) => ({ label: unit.unitName, value: unit.unitId })),
277
+ ], [roomUnits, merged.noRoom]);
278
+ return (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border p-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { children: merged.heading }), _jsx(Button, { type: "button", size: "sm", variant: "ghost", onClick: addRow, children: merged.addTraveler })] }), billingPersonId && !hasBillingPersonTraveler ? (_jsx("div", { children: _jsxs(Button, { type: "button", size: "sm", variant: "outline", onClick: addBillingPerson, disabled: !billingPerson.data, children: [_jsx(UserPlus, { className: "mr-1 h-3.5 w-3.5" }), merged.addBillingPerson] }) })) : null, relatedPersonIds.length > 0 ? (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: merged.relatedPeopleHeading }), _jsx("div", { className: "flex flex-wrap gap-1.5", children: relatedPersonIds.map((rel) => (_jsx(RelatedPersonChip, { personId: rel.id, kind: rel.kind, addLabel: merged.addRelatedPerson, onAdd: addRelatedPersonTraveler }, rel.id))) })] })) : null, value.travelers.length === 0 ? (_jsx("p", { className: "text-xs text-muted-foreground", children: merged.empty })) : (_jsx("div", { className: "flex flex-col gap-2", children: value.travelers.map((traveler, index) => (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border p-2", children: [_jsx(TravelerPersonPicker, { personId: traveler.personId, labels: merged, pinnedPeople: billingPerson.data ? [billingPerson.data] : [], onSelect: (person) => updateAt(index, {
279
+ personId: person.id,
280
+ firstName: person.firstName,
281
+ lastName: person.lastName,
282
+ email: person.email ?? "",
283
+ phone: person.phone ?? "",
284
+ preferredLanguage: person.preferredLanguage ?? "",
285
+ dateOfBirth: person.dateOfBirth ?? null,
286
+ // Re-derive auto-owned unit assignments when the
287
+ // linked CRM person changes. Pricing and inventory
288
+ // stay independent: a manual room does not freeze
289
+ // DOB-driven pricing, and a manual category does
290
+ // not move the room.
291
+ ...(traveler.pricingUnitSource === "manual" ||
292
+ traveler.pricingUnitSource === "none"
293
+ ? {}
294
+ : {
295
+ pricingUnitId: pickPricingUnitIdForTraveler(person.dateOfBirth ?? null, traveler.role, traveler.inventoryUnitId),
296
+ pricingUnitSource: "auto",
297
+ }),
298
+ pricingCategoryId: matchPricingCategoryForTraveler(pricingCategories, person.dateOfBirth ?? null, traveler.role, traveler.inventoryUnitId),
299
+ ...(traveler.inventoryUnitSource === "manual" ||
300
+ traveler.inventoryUnitSource === "none"
301
+ ? {}
302
+ : {
303
+ inventoryUnitId: pickAssignmentsForNewTraveler(person.dateOfBirth ?? null, traveler.role).inventoryUnitId,
304
+ inventoryUnitSource: "auto",
305
+ }),
306
+ }), onClear: () => updateAt(index, {
307
+ personId: null,
308
+ firstName: "",
309
+ lastName: "",
310
+ email: "",
311
+ phone: "",
312
+ preferredLanguage: "",
313
+ dateOfBirth: null,
314
+ ...(traveler.pricingUnitSource === "manual" ||
315
+ traveler.pricingUnitSource === "none"
316
+ ? {}
317
+ : {
318
+ pricingUnitId: pickPricingUnitIdForTraveler(null, traveler.role, traveler.inventoryUnitId),
319
+ pricingUnitSource: "auto",
320
+ }),
321
+ pricingCategoryId: matchPricingCategoryForTraveler(pricingCategories, null, traveler.role, traveler.inventoryUnitId),
322
+ ...(traveler.inventoryUnitSource === "manual" ||
323
+ traveler.inventoryUnitSource === "none"
324
+ ? {}
325
+ : {
326
+ inventoryUnitId: pickAssignmentsForNewTraveler(null, traveler.role)
327
+ .inventoryUnitId,
328
+ inventoryUnitSource: "auto",
329
+ }),
330
+ }) }), _jsxs("div", { className: "grid grid-cols-2 gap-2", children: [pricingCategories ? (_jsx(TravelerPricingCategorySelect, { traveler: traveler, categories: pricingCategories, label: merged.category, onPickCategory: (category) => updateAt(index, {
331
+ pricingCategoryId: category.categoryId,
332
+ role: traveler.role === "lead" &&
333
+ roleFromPricingCategoryType(category.categoryType) === "adult"
334
+ ? "lead"
335
+ : roleFromPricingCategoryType(category.categoryType),
336
+ }) })) : (_jsx(TravelerCategoryButtons, { traveler: traveler, roomGroups: roomGroups, fallbackLabels: {
337
+ category: merged.category,
338
+ adult: merged.roleAdult,
339
+ child: merged.roleChild,
340
+ infant: merged.roleInfant,
341
+ }, onPickUnit: (unitId, nextRole, source) => updateAt(index, {
342
+ pricingUnitId: unitId,
343
+ role: nextRole,
344
+ // Only freeze as manual when the dynamic button
345
+ // actually picked a unit. Role-only clicks via
346
+ // the static fallback stay `auto` so the
347
+ // resolver can re-derive once real units load.
348
+ pricingUnitSource: source,
349
+ }) })), roomUnits && roomUnits.length > 0 ? (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-xs", children: merged.room }), _jsxs(Select, { items: roomSelectItems, value: traveler.inventoryUnitId ?? NO_ROOM, onValueChange: (v) => updateAt(index, {
350
+ inventoryUnitId: v === NO_ROOM || !v ? null : v,
351
+ inventoryUnitSource: v === NO_ROOM || !v ? "none" : "manual",
352
+ pricingCategoryId: matchPricingCategoryForTraveler(pricingCategories, traveler.dateOfBirth, traveler.role, v === NO_ROOM || !v ? null : v),
353
+ }), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: NO_ROOM, children: merged.noRoom }), roomUnits.map((unit) => (_jsx(SelectItem, { value: unit.unitId, disabled: unit.remainingCapacity <= 0 &&
354
+ traveler.inventoryUnitId !== unit.unitId, children: unit.unitName }, unit.unitId)))] })] })] })) : null] }), _jsx("div", { className: "flex justify-end", children: _jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 text-destructive", onClick: () => removeAt(index), "aria-label": merged.remove, children: [_jsx(Trash2, { className: "mr-1 h-3.5 w-3.5" }), merged.remove] }) })] }, index))) }))] }));
355
+ }
@@ -0,0 +1,50 @@
1
+ /** Details of a successfully-validated voucher. */
2
+ export interface PickedVoucher {
3
+ id: string;
4
+ code: string;
5
+ label: string | null;
6
+ currency: string | null;
7
+ remainingAmountCents: number | null;
8
+ expiresAt: string | null;
9
+ }
10
+ export interface VoucherPickerValue {
11
+ /** Code typed by the operator. Not cleared on failure so they can correct a typo. */
12
+ code: string;
13
+ /** Populated only when the last validate call succeeded. */
14
+ picked: PickedVoucher | null;
15
+ /** Reason returned by the server when validate fails, or a client-side message. */
16
+ error: string | null;
17
+ }
18
+ export declare const emptyVoucherPickerValue: VoucherPickerValue;
19
+ export interface VoucherPickerSectionProps {
20
+ value: VoucherPickerValue;
21
+ onChange: (value: VoucherPickerValue) => void;
22
+ /**
23
+ * Context for the validate call — when provided, the server rejects vouchers
24
+ * locked to a different booking / mismatched currency / insufficient balance.
25
+ */
26
+ bookingId?: string;
27
+ currency?: string;
28
+ amountCents?: number;
29
+ labels?: {
30
+ heading?: string;
31
+ codePlaceholder?: string;
32
+ apply?: string;
33
+ clear?: string;
34
+ remainingLabel?: string;
35
+ invalidLabel?: string;
36
+ };
37
+ }
38
+ /**
39
+ * Voucher picker for booking-create flows. Operator enters a code, clicks
40
+ * Apply, and the server-side `/v1/public/vouchers/validate` runs all the
41
+ * usual guards (status, expiry, currency, booking-assignment, balance).
42
+ *
43
+ * The section only *validates* — it doesn't redeem. Redemption happens when
44
+ * the parent calls `POST /v1/finance/vouchers/:id/redeem` at submit time,
45
+ * after the booking exists and the final amount is known. Validate being
46
+ * idempotent means the operator can try a code, correct a typo, and try
47
+ * again without leaving a trail.
48
+ */
49
+ export declare function VoucherPickerSection({ value, onChange, bookingId, currency, amountCents, labels, }: VoucherPickerSectionProps): import("react/jsx-runtime").JSX.Element;
50
+ //# sourceMappingURL=voucher-picker-section.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voucher-picker-section.d.ts","sourceRoot":"","sources":["../../src/components/voucher-picker-section.tsx"],"names":[],"mappings":"AAOA,mDAAmD;AACnD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAA;IACZ,4DAA4D;IAC5D,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;IAC5B,mFAAmF;IACnF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,eAAO,MAAM,uBAAuB,EAAE,kBAIrC,CAAA;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,kBAAkB,CAAA;IACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAA;IAC7C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,WAAW,EACX,MAAM,GACP,EAAE,yBAAyB,2CAiH3B"}
@@ -0,0 +1,79 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { usePublicVoucherValidationMutation } from "@voyant-travel/finance-react";
4
+ import { Button, Input, Label } from "@voyant-travel/ui/components";
5
+ import { CheckCircle2, Loader2, XCircle } from "lucide-react";
6
+ import { useBookingsUiI18nOrDefault, useBookingsUiMessagesOrDefault } from "../i18n/provider.js";
7
+ export const emptyVoucherPickerValue = {
8
+ code: "",
9
+ picked: null,
10
+ error: null,
11
+ };
12
+ /**
13
+ * Voucher picker for booking-create flows. Operator enters a code, clicks
14
+ * Apply, and the server-side `/v1/public/vouchers/validate` runs all the
15
+ * usual guards (status, expiry, currency, booking-assignment, balance).
16
+ *
17
+ * The section only *validates* — it doesn't redeem. Redemption happens when
18
+ * the parent calls `POST /v1/finance/vouchers/:id/redeem` at submit time,
19
+ * after the booking exists and the final amount is known. Validate being
20
+ * idempotent means the operator can try a code, correct a typo, and try
21
+ * again without leaving a trail.
22
+ */
23
+ export function VoucherPickerSection({ value, onChange, bookingId, currency, amountCents, labels, }) {
24
+ const { formatCurrency } = useBookingsUiI18nOrDefault();
25
+ const messages = useBookingsUiMessagesOrDefault();
26
+ const merged = { ...messages.voucherPickerSection.labels, ...labels };
27
+ const validate = usePublicVoucherValidationMutation();
28
+ const handleApply = async () => {
29
+ const code = value.code.trim();
30
+ if (!code)
31
+ return;
32
+ try {
33
+ const { data } = await validate.mutateAsync({
34
+ code,
35
+ bookingId: bookingId ?? undefined,
36
+ currency: currency ?? undefined,
37
+ amountCents: amountCents ?? undefined,
38
+ });
39
+ if (data.valid && data.voucher) {
40
+ onChange({
41
+ code,
42
+ picked: {
43
+ id: data.voucher.id,
44
+ code: data.voucher.code,
45
+ label: data.voucher.label,
46
+ currency: data.voucher.currency,
47
+ remainingAmountCents: data.voucher.remainingAmountCents,
48
+ expiresAt: data.voucher.expiresAt,
49
+ },
50
+ error: null,
51
+ });
52
+ return;
53
+ }
54
+ onChange({
55
+ code,
56
+ picked: null,
57
+ error: messages.voucherPickerSection.reasonMessages[data.reason] ?? messages.voucherPickerSection.validation.invalid,
58
+ });
59
+ }
60
+ catch (err) {
61
+ onChange({
62
+ code,
63
+ picked: null,
64
+ error: err instanceof Error
65
+ ? err.message
66
+ : messages.voucherPickerSection.validation.lookupFailed,
67
+ });
68
+ }
69
+ };
70
+ const handleClear = () => onChange(emptyVoucherPickerValue);
71
+ return (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border p-3", children: [_jsx(Label, { children: merged.heading }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { value: value.code, onChange: (e) => onChange({ ...value, code: e.target.value, error: null }), onKeyDown: (e) => {
72
+ if (e.key === "Enter") {
73
+ e.preventDefault();
74
+ void handleApply();
75
+ }
76
+ }, placeholder: merged.codePlaceholder, disabled: validate.isPending || Boolean(value.picked) }), value.picked ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: handleClear, children: merged.clear })) : (_jsxs(Button, { type: "button", size: "sm", onClick: () => void handleApply(), disabled: validate.isPending || !value.code.trim(), children: [validate.isPending && _jsx(Loader2, { className: "mr-1 h-3.5 w-3.5 animate-spin" }), merged.apply] }))] }), value.picked && (_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-600" }), _jsxs("span", { children: [merged.remainingLabel, " ", _jsx("strong", { children: value.picked.remainingAmountCents == null || !value.picked.currency
77
+ ? messages.voucherPickerSection.validation.amountUnavailable
78
+ : formatCurrency(value.picked.remainingAmountCents / 100, value.picked.currency) })] })] })), value.error && (_jsxs("div", { className: "flex items-start gap-2 text-sm text-destructive", children: [_jsx(XCircle, { className: "mt-0.5 h-4 w-4" }), _jsxs("span", { children: [merged.invalidLabel, " ", value.error] })] }))] }));
79
+ }
@@ -0,0 +1,14 @@
1
+ import type { z } from "zod";
2
+ export type VoyantFetcher = (url: string, init?: RequestInit) => Promise<Response>;
3
+ export declare const defaultFetcher: VoyantFetcher;
4
+ export declare class VoyantApiError extends Error {
5
+ readonly status: number;
6
+ readonly body: unknown;
7
+ constructor(message: string, status: number, body: unknown);
8
+ }
9
+ export interface FetchWithValidationOptions {
10
+ baseUrl: string;
11
+ fetcher: VoyantFetcher;
12
+ }
13
+ export declare function fetchWithValidation<TOut>(path: string, schema: z.ZodType<TOut>, options: FetchWithValidationOptions, init?: RequestInit): Promise<TOut>;
14
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/extras/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAE5B,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAElF,eAAO,MAAM,cAAc,EAAE,aACoB,CAAA;AAEjD,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;gBAEV,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;CAM3D;AAaD,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,aAAa,CAAA;CACvB;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAC5C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EACvB,OAAO,EAAE,0BAA0B,EACnC,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
@@ -0,0 +1,58 @@
1
+ export const defaultFetcher = (url, init) => fetch(url, { credentials: "include", ...init });
2
+ export class VoyantApiError extends Error {
3
+ status;
4
+ body;
5
+ constructor(message, status, body) {
6
+ super(message);
7
+ this.name = "VoyantApiError";
8
+ this.status = status;
9
+ this.body = body;
10
+ }
11
+ }
12
+ function extractErrorMessage(status, statusText, body) {
13
+ if (typeof body === "object" && body !== null && "error" in body) {
14
+ const err = body.error;
15
+ if (typeof err === "string")
16
+ return err;
17
+ if (typeof err === "object" && err !== null && "message" in err) {
18
+ return String(err.message);
19
+ }
20
+ }
21
+ return `Voyant API error: ${status} ${statusText}`;
22
+ }
23
+ export async function fetchWithValidation(path, schema, options, init) {
24
+ const url = joinUrl(options.baseUrl, path);
25
+ const headers = new Headers(init?.headers);
26
+ if (init?.body !== undefined && !headers.has("Content-Type")) {
27
+ headers.set("Content-Type", "application/json");
28
+ }
29
+ const response = await options.fetcher(url, { ...init, headers });
30
+ if (!response.ok) {
31
+ const body = await safeJson(response);
32
+ throw new VoyantApiError(extractErrorMessage(response.status, response.statusText, body), response.status, body);
33
+ }
34
+ if (response.status === 204)
35
+ return schema.parse(undefined);
36
+ const body = await safeJson(response);
37
+ const parsed = schema.safeParse(body);
38
+ if (!parsed.success) {
39
+ throw new VoyantApiError(`Voyant API response failed validation: ${parsed.error.message}`, response.status, body);
40
+ }
41
+ return parsed.data;
42
+ }
43
+ async function safeJson(response) {
44
+ const text = await response.text();
45
+ if (!text)
46
+ return undefined;
47
+ try {
48
+ return JSON.parse(text);
49
+ }
50
+ catch {
51
+ return text;
52
+ }
53
+ }
54
+ function joinUrl(baseUrl, path) {
55
+ const trimmedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
56
+ const trimmedPath = path.startsWith("/") ? path : `/${path}`;
57
+ return `${trimmedBase}${trimmedPath}`;
58
+ }
@@ -0,0 +1,13 @@
1
+ import type { CatalogSearchHit } from "@voyant-travel/catalog-react";
2
+ export interface ExtraCatalogCardProps {
3
+ hit: CatalogSearchHit;
4
+ onClick?: (hit: CatalogSearchHit) => void;
5
+ className?: string;
6
+ }
7
+ /**
8
+ * Search-result card for an extras hit (sub-line-item add-ons attached
9
+ * to bookings). Reads: `name`, `category`, `priceCents`, `currency`,
10
+ * `unit` (per_person | per_booking | per_night), `tags`.
11
+ */
12
+ export declare function ExtraCatalogCard({ hit, onClick, className }: ExtraCatalogCardProps): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=extra-catalog-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extra-catalog-card.d.ts","sourceRoot":"","sources":["../../../src/extras/components/extra-catalog-card.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAMpE,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,gBAAgB,CAAA;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,qBAAqB,2CA8DlF"}
@@ -0,0 +1,52 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Badge } from "@voyant-travel/ui/components/badge";
4
+ import { Card, CardContent } from "@voyant-travel/ui/components/card";
5
+ import { cn } from "@voyant-travel/ui/lib/utils";
6
+ import { useExtrasUiI18nOrDefault } from "../i18n/index.js";
7
+ /**
8
+ * Search-result card for an extras hit (sub-line-item add-ons attached
9
+ * to bookings). Reads: `name`, `category`, `priceCents`, `currency`,
10
+ * `unit` (per_person | per_booking | per_night), `tags`.
11
+ */
12
+ export function ExtraCatalogCard({ hit, onClick, className }) {
13
+ const i18n = useExtrasUiI18nOrDefault();
14
+ const messages = i18n.messages.catalogCard;
15
+ const f = hit.document.fields;
16
+ const name = stringOr(f.name, messages.untitled);
17
+ const category = stringOr(f.category, null);
18
+ const unit = stringOr(f.unit, null);
19
+ const status = stringOr(f.status, null);
20
+ const tags = stringArray(f.tags);
21
+ const price = numberOr(f.priceCents, null);
22
+ const currency = stringOr(f.currency ?? f.sellCurrency, null);
23
+ const priceLabel = price != null && currency
24
+ ? i18n.formatCurrency(price / 100, currency, {
25
+ maximumFractionDigits: 2,
26
+ })
27
+ : null;
28
+ return (_jsx(Card, { className: cn("h-full cursor-pointer transition-colors hover:border-primary/40", onClick == null && "cursor-default", className), onClick: onClick ? () => onClick(hit) : undefined, children: _jsxs(CardContent, { className: "flex h-full flex-col gap-2 p-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsx("h3", { className: "line-clamp-2 font-medium text-sm", children: name }), status && (_jsx(Badge, { variant: status === "active" ? "default" : "secondary", className: "shrink-0", children: status }))] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2 text-muted-foreground text-xs", children: [category && _jsx("span", { children: category }), priceLabel && (_jsxs("span", { className: "ml-auto font-medium text-foreground", children: [priceLabel, unit && (_jsx("span", { className: "ml-1 text-muted-foreground", children: formatTemplate(messages.unitPrefix, { unit: unit.replace(/_/g, " ") }) }))] }))] }), tags.length > 0 && (_jsx("div", { className: "mt-auto flex flex-wrap gap-1", children: tags.slice(0, 4).map((tag) => (_jsx(Badge, { variant: "outline", className: "text-[10px]", children: tag }, tag))) }))] }) }));
29
+ }
30
+ function formatTemplate(template, values) {
31
+ return template.replace(/\{(\w+)\}/g, (_, key) => {
32
+ const value = values[key];
33
+ return value === undefined ? "" : String(value);
34
+ });
35
+ }
36
+ function stringOr(value, fallback) {
37
+ return typeof value === "string" && value.length > 0 ? value : fallback;
38
+ }
39
+ function numberOr(value, fallback) {
40
+ if (typeof value === "number")
41
+ return value;
42
+ if (typeof value === "string") {
43
+ const n = Number(value);
44
+ return Number.isFinite(n) ? n : fallback;
45
+ }
46
+ return fallback;
47
+ }
48
+ function stringArray(value) {
49
+ if (!Array.isArray(value))
50
+ return [];
51
+ return value.filter((v) => typeof v === "string" && v.length > 0);
52
+ }
@@ -0,0 +1,9 @@
1
+ type Props = {
2
+ value: string | null | undefined;
3
+ onChange: (value: string | null) => void;
4
+ placeholder?: string;
5
+ disabled?: boolean;
6
+ };
7
+ export declare function ProductCombobox({ value, onChange, placeholder, disabled }: Props): import("react/jsx-runtime").JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=product-combobox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-combobox.d.ts","sourceRoot":"","sources":["../../../src/extras/components/product-combobox.tsx"],"names":[],"mappings":"AAgBA,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAID,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAyEhF"}