@wealthx/shadcn 1.4.0 → 1.5.0

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 (430) hide show
  1. package/.turbo/turbo-build.log +360 -180
  2. package/CHANGELOG.md +12 -0
  3. package/dist/chunk-2A53WPEC.mjs +182 -0
  4. package/dist/{chunk-SIVYAI3M.mjs → chunk-2LLFNGJZ.mjs} +15 -15
  5. package/dist/chunk-2QNOPXMQ.mjs +360 -0
  6. package/dist/{chunk-K5QV4TT6.mjs → chunk-2WCIORP7.mjs} +29 -4
  7. package/dist/{chunk-5NF6T2RS.mjs → chunk-3AREQTZU.mjs} +8 -8
  8. package/dist/{chunk-2EM2FRU6.mjs → chunk-3WGFIFP6.mjs} +5 -5
  9. package/dist/{chunk-K4KOD3KR.mjs → chunk-42NEC57Y.mjs} +44 -25
  10. package/dist/{chunk-FL6DZFJK.mjs → chunk-46Q4335I.mjs} +121 -39
  11. package/dist/chunk-4DO3WM7V.mjs +48 -0
  12. package/dist/chunk-5FHBC6DY.mjs +68 -0
  13. package/dist/chunk-5SAYZ4CI.mjs +40 -0
  14. package/dist/chunk-5WMFKQZ6.mjs +180 -0
  15. package/dist/chunk-623YVI5O.mjs +43 -0
  16. package/dist/{chunk-SFH2NJEJ.mjs → chunk-6OSULDEO.mjs} +3 -3
  17. package/dist/{chunk-UALR6JGV.mjs → chunk-6SR4K5T5.mjs} +1 -1
  18. package/dist/{chunk-D2NSIIXG.mjs → chunk-7KT5HPYM.mjs} +11 -11
  19. package/dist/chunk-A6ER36CW.mjs +456 -0
  20. package/dist/{chunk-QX7IFQSF.mjs → chunk-AHKHVBWR.mjs} +4 -4
  21. package/dist/chunk-AHSCWXYJ.mjs +113 -0
  22. package/dist/{chunk-7GWRPXHD.mjs → chunk-AL6GOL2Y.mjs} +1 -1
  23. package/dist/{chunk-OIKBW2QD.mjs → chunk-AUEUTZIC.mjs} +13 -13
  24. package/dist/{chunk-FYPSTTEJ.mjs → chunk-B7DD3ODQ.mjs} +1 -1
  25. package/dist/{chunk-TLAWKTSA.mjs → chunk-BD3DWDT4.mjs} +3 -3
  26. package/dist/{chunk-S2FKV4M5.mjs → chunk-BDESHD25.mjs} +4 -4
  27. package/dist/{chunk-OKTJFDPN.mjs → chunk-BFB3UH7V.mjs} +2 -2
  28. package/dist/{chunk-DGNHGNYH.mjs → chunk-C6SWS7OW.mjs} +1 -1
  29. package/dist/chunk-CDVG7SFT.mjs +271 -0
  30. package/dist/chunk-CUSHAIUL.mjs +109 -0
  31. package/dist/{chunk-QXKGOMUX.mjs → chunk-CW32WTZU.mjs} +4 -4
  32. package/dist/{chunk-SET2ANTY.mjs → chunk-D447W45Z.mjs} +3 -3
  33. package/dist/{chunk-RCAOCHWA.mjs → chunk-DFL5CV75.mjs} +18 -18
  34. package/dist/chunk-DYSVJ473.mjs +162 -0
  35. package/dist/chunk-E3PQDBYI.mjs +288 -0
  36. package/dist/chunk-EMYBNPIA.mjs +83 -0
  37. package/dist/chunk-EUYPMDQG.mjs +348 -0
  38. package/dist/{chunk-XYPW2XA5.mjs → chunk-EW72FINW.mjs} +11 -11
  39. package/dist/chunk-F24U4QQQ.mjs +234 -0
  40. package/dist/{chunk-VB5M6OZQ.mjs → chunk-F4O2YPXJ.mjs} +1 -1
  41. package/dist/chunk-FFXTQTB4.mjs +84 -0
  42. package/dist/{chunk-ZOWL2L5J.mjs → chunk-FYUSF5KO.mjs} +5 -1
  43. package/dist/{chunk-FTPBQVQ6.mjs → chunk-GNER6MCO.mjs} +1 -1
  44. package/dist/{chunk-2D3HQPFN.mjs → chunk-HF4FUBCY.mjs} +5 -5
  45. package/dist/{chunk-RSUIPKGX.mjs → chunk-HNDTLT5X.mjs} +1 -1
  46. package/dist/{chunk-N6Q5IPKT.mjs → chunk-HO6S3ECM.mjs} +46 -18
  47. package/dist/{chunk-L4NSRQ3T.mjs → chunk-HROG643K.mjs} +1 -1
  48. package/dist/chunk-I2EKKSEF.mjs +148 -0
  49. package/dist/{chunk-QTRSCVQ3.mjs → chunk-I3UDLWQ7.mjs} +1 -1
  50. package/dist/{chunk-AE7MASLF.mjs → chunk-IQGKOT7A.mjs} +9 -6
  51. package/dist/chunk-IXR4BQSQ.mjs +290 -0
  52. package/dist/{chunk-4MM7LHM5.mjs → chunk-J5NW5NCT.mjs} +1 -1
  53. package/dist/{chunk-OLKMCXAR.mjs → chunk-JTG5R5YV.mjs} +24 -24
  54. package/dist/chunk-JUBUN65Q.mjs +106 -0
  55. package/dist/chunk-K7TWMLLW.mjs +520 -0
  56. package/dist/{chunk-BOW7U26Y.mjs → chunk-K7WSRWOU.mjs} +4 -4
  57. package/dist/{chunk-NTYQWVLI.mjs → chunk-KAD26MCC.mjs} +1 -1
  58. package/dist/{chunk-KCWNDYPZ.mjs → chunk-KB7MZMED.mjs} +4 -4
  59. package/dist/chunk-KCKYGQVQ.mjs +61 -0
  60. package/dist/{chunk-VY5NEUP7.mjs → chunk-KLJLDNCA.mjs} +1 -1
  61. package/dist/chunk-LLAGF6BA.mjs +49 -0
  62. package/dist/{chunk-G27TSQLQ.mjs → chunk-M4LTX3MH.mjs} +1 -1
  63. package/dist/{chunk-YIZHS72Z.mjs → chunk-MHHA7QGO.mjs} +94 -54
  64. package/dist/{chunk-P2N2PEFY.mjs → chunk-NCUH54IZ.mjs} +4 -4
  65. package/dist/{chunk-PNRUH7JY.mjs → chunk-OECGKCVF.mjs} +5 -5
  66. package/dist/{chunk-YE67AALL.mjs → chunk-OL65UQHQ.mjs} +10 -10
  67. package/dist/{chunk-LQULK2E3.mjs → chunk-OYBIUEGE.mjs} +1 -1
  68. package/dist/{chunk-LR6LHDP3.mjs → chunk-PGR53HMH.mjs} +7 -7
  69. package/dist/chunk-PUJ42INK.mjs +141 -0
  70. package/dist/{chunk-M4VYX2PV.mjs → chunk-PV3Y7QGK.mjs} +2 -2
  71. package/dist/{chunk-UJZ4UHWI.mjs → chunk-PV7PNA6K.mjs} +4 -4
  72. package/dist/{chunk-6HIOM2HL.mjs → chunk-Q35PNFJ7.mjs} +1 -1
  73. package/dist/{chunk-JZY6TNIS.mjs → chunk-Q5SGEIJV.mjs} +27 -27
  74. package/dist/{chunk-ZFCDYW6N.mjs → chunk-QAX6HCUH.mjs} +1 -1
  75. package/dist/chunk-QHJDGB54.mjs +135 -0
  76. package/dist/chunk-QQSOZQOC.mjs +27 -0
  77. package/dist/chunk-RUX3OLVZ.mjs +59 -0
  78. package/dist/{chunk-QOJ2DQD6.mjs → chunk-S4CTM3UE.mjs} +5 -0
  79. package/dist/{chunk-ZEDMKQK2.mjs → chunk-TAX3KL66.mjs} +1 -1
  80. package/dist/chunk-TC43SMIN.mjs +133 -0
  81. package/dist/chunk-TGVXRD53.mjs +174 -0
  82. package/dist/{chunk-K5VHK7CM.mjs → chunk-TLYSVRSK.mjs} +12 -12
  83. package/dist/{chunk-YCWLFG27.mjs → chunk-TOIVHWNC.mjs} +1 -1
  84. package/dist/chunk-TXUBGKB7.mjs +160 -0
  85. package/dist/chunk-UEREFDAE.mjs +75 -0
  86. package/dist/chunk-UTCQN6XU.mjs +123 -0
  87. package/dist/{chunk-37AE3OM5.mjs → chunk-V4CUTCHS.mjs} +4 -4
  88. package/dist/{chunk-THVO2N47.mjs → chunk-VFH632TB.mjs} +9 -9
  89. package/dist/{chunk-3ERBUVHC.mjs → chunk-VJ3GC7W3.mjs} +95 -49
  90. package/dist/{chunk-V6XGXYCJ.mjs → chunk-VLELWBEW.mjs} +4 -4
  91. package/dist/{chunk-FEZKMUCF.mjs → chunk-WDTXHLYM.mjs} +1 -1
  92. package/dist/chunk-WUA546RX.mjs +129 -0
  93. package/dist/chunk-XHGISOX5.mjs +257 -0
  94. package/dist/chunk-XIY5DJXI.mjs +168 -0
  95. package/dist/{chunk-TOWTPLRC.mjs → chunk-XN37434W.mjs} +8 -8
  96. package/dist/{chunk-KLTACJ2G.mjs → chunk-XTWAJWCQ.mjs} +1 -1
  97. package/dist/chunk-Y24TXIFJ.mjs +518 -0
  98. package/dist/{chunk-DMXYRCHM.mjs → chunk-Y6UM3VTN.mjs} +4 -4
  99. package/dist/components/ui/about-you-form.js +1120 -0
  100. package/dist/components/ui/about-you-form.mjs +323 -0
  101. package/dist/components/ui/account-list-carousel.js +304 -0
  102. package/dist/components/ui/account-list-carousel.mjs +11 -0
  103. package/dist/components/ui/add-column-modal.js +1 -1
  104. package/dist/components/ui/add-column-modal.mjs +6 -6
  105. package/dist/components/ui/add-lead-modal.js +2 -2
  106. package/dist/components/ui/add-lead-modal.mjs +6 -6
  107. package/dist/components/ui/advisor-card.mjs +2 -2
  108. package/dist/components/ui/agent-evaluation-toast.js +299 -0
  109. package/dist/components/ui/agent-evaluation-toast.mjs +12 -0
  110. package/dist/components/ui/ai-assistant-drawer.mjs +5 -5
  111. package/dist/components/ui/ai-builder.js +3 -3
  112. package/dist/components/ui/ai-builder.mjs +5 -5
  113. package/dist/components/ui/ai-conversations.js +2 -2
  114. package/dist/components/ui/ai-conversations.mjs +11 -11
  115. package/dist/components/ui/alert-dialog.mjs +3 -3
  116. package/dist/components/ui/applicant-document-checklist.js +346 -0
  117. package/dist/components/ui/applicant-document-checklist.mjs +10 -0
  118. package/dist/components/ui/applicant-expenses-section.js +455 -0
  119. package/dist/components/ui/applicant-expenses-section.mjs +220 -0
  120. package/dist/components/ui/applicant-navigation-bar.js +309 -0
  121. package/dist/components/ui/applicant-navigation-bar.mjs +87 -0
  122. package/dist/components/ui/applicant-switcher.js +268 -0
  123. package/dist/components/ui/applicant-switcher.mjs +46 -0
  124. package/dist/components/ui/application-mobile-layout.js +88 -0
  125. package/dist/components/ui/application-mobile-layout.mjs +8 -0
  126. package/dist/components/ui/appointment-action-dialogs.js +1 -1
  127. package/dist/components/ui/appointment-action-dialogs.mjs +10 -10
  128. package/dist/components/ui/appointment-availability-settings.js +78 -31
  129. package/dist/components/ui/appointment-availability-settings.mjs +12 -10
  130. package/dist/components/ui/appointment-book-dialog.js +137 -58
  131. package/dist/components/ui/appointment-book-dialog.mjs +14 -14
  132. package/dist/components/ui/appointment-calendar-view.js +1 -1
  133. package/dist/components/ui/appointment-calendar-view.mjs +4 -4
  134. package/dist/components/ui/appointment-detail-sheet.js +38 -11
  135. package/dist/components/ui/appointment-detail-sheet.mjs +13 -13
  136. package/dist/components/ui/appointment-gmail-connect.mjs +2 -2
  137. package/dist/components/ui/appointment-time-slot-picker.mjs +2 -2
  138. package/dist/components/ui/appointment-upcoming-card.js +1 -1
  139. package/dist/components/ui/appointment-upcoming-card.mjs +10 -10
  140. package/dist/components/ui/asset-accordion.js +506 -0
  141. package/dist/components/ui/asset-accordion.mjs +202 -0
  142. package/dist/components/ui/assets-liabilities-side-card.js +328 -0
  143. package/dist/components/ui/assets-liabilities-side-card.mjs +127 -0
  144. package/dist/components/ui/auth-page-layout.js +3 -3
  145. package/dist/components/ui/auth-page-layout.mjs +1 -1
  146. package/dist/components/ui/backoffice-alert-history-chart.mjs +4 -4
  147. package/dist/components/ui/backoffice-alert-matching-chart.js +786 -0
  148. package/dist/components/ui/backoffice-alert-matching-chart.mjs +19 -0
  149. package/dist/components/ui/backoffice-alerts-chart.mjs +4 -4
  150. package/dist/components/ui/backoffice-connections-chart.mjs +4 -4
  151. package/dist/components/ui/backoffice-contact-history-chart.mjs +4 -4
  152. package/dist/components/ui/backoffice-contact-matching-chart.js +803 -0
  153. package/dist/components/ui/backoffice-contact-matching-chart.mjs +19 -0
  154. package/dist/components/ui/backoffice-signup-steps.js +1673 -0
  155. package/dist/components/ui/backoffice-signup-steps.mjs +36 -0
  156. package/dist/components/ui/bank-statement-document-table.js +467 -0
  157. package/dist/components/ui/bank-statement-document-table.mjs +12 -0
  158. package/dist/components/ui/bank-statement-generate-dialog.js +1517 -0
  159. package/dist/components/ui/bank-statement-generate-dialog.mjs +27 -0
  160. package/dist/components/ui/bank-statement-pdf-viewer.js +525 -0
  161. package/dist/components/ui/bank-statement-pdf-viewer.mjs +14 -0
  162. package/dist/components/ui/banking-accounts-connect.js +336 -0
  163. package/dist/components/ui/banking-accounts-connect.mjs +114 -0
  164. package/dist/components/ui/borrowing-capacity-atoms.js +382 -0
  165. package/dist/components/ui/borrowing-capacity-atoms.mjs +17 -0
  166. package/dist/components/ui/borrowing-capacity-card.js +835 -0
  167. package/dist/components/ui/borrowing-capacity-card.mjs +89 -0
  168. package/dist/components/ui/borrowing-capacity-line-chart.mjs +4 -4
  169. package/dist/components/ui/broker-info-panel.js +281 -0
  170. package/dist/components/ui/broker-info-panel.mjs +59 -0
  171. package/dist/components/ui/calculator-input-item.js +101 -0
  172. package/dist/components/ui/calculator-input-item.mjs +8 -0
  173. package/dist/components/ui/calculator-section.js +743 -0
  174. package/dist/components/ui/calculator-section.mjs +220 -0
  175. package/dist/components/ui/calendar.mjs +2 -2
  176. package/dist/components/ui/cash-balance-line-chart.mjs +5 -5
  177. package/dist/components/ui/cashflow-bar-chart.mjs +4 -4
  178. package/dist/components/ui/category-edit-dialog.js +737 -0
  179. package/dist/components/ui/category-edit-dialog.mjs +16 -0
  180. package/dist/components/ui/chat-widget.mjs +3 -3
  181. package/dist/components/ui/color-picker.mjs +4 -4
  182. package/dist/components/ui/connect-bank-step.js +511 -0
  183. package/dist/components/ui/connect-bank-step.mjs +287 -0
  184. package/dist/components/ui/contact-alert-dialog.js +1405 -0
  185. package/dist/components/ui/contact-alert-dialog.mjs +27 -0
  186. package/dist/components/ui/create-contact-modal.js +1028 -0
  187. package/dist/components/ui/create-contact-modal.mjs +21 -0
  188. package/dist/components/ui/csv-import-modal.js +583 -0
  189. package/dist/components/ui/csv-import-modal.mjs +14 -0
  190. package/dist/components/ui/currency-input.js +439 -0
  191. package/dist/components/ui/currency-input.mjs +13 -0
  192. package/dist/components/ui/dashboard-expense-categories.js +355 -0
  193. package/dist/components/ui/dashboard-expense-categories.mjs +186 -0
  194. package/dist/components/ui/dashboard-transactions-table.js +1083 -0
  195. package/dist/components/ui/dashboard-transactions-table.mjs +177 -0
  196. package/dist/components/ui/data-table.mjs +6 -6
  197. package/dist/components/ui/date-picker.mjs +6 -6
  198. package/dist/components/ui/debt-accordion.js +523 -0
  199. package/dist/components/ui/debt-accordion.mjs +219 -0
  200. package/dist/components/ui/delete-contact-component.js +479 -0
  201. package/dist/components/ui/delete-contact-component.mjs +14 -0
  202. package/dist/components/ui/dialog.js +1 -1
  203. package/dist/components/ui/dialog.mjs +3 -3
  204. package/dist/components/ui/document-checklist-template.mjs +4 -4
  205. package/dist/components/ui/drawer.mjs +3 -3
  206. package/dist/components/ui/dropdown-menu.mjs +3 -3
  207. package/dist/components/ui/dynamic-tabs.js +274 -0
  208. package/dist/components/ui/dynamic-tabs.mjs +116 -0
  209. package/dist/components/ui/editable-money-item.js +306 -0
  210. package/dist/components/ui/editable-money-item.mjs +12 -0
  211. package/dist/components/ui/expense-bar-chart.mjs +4 -4
  212. package/dist/components/ui/expense-detail-item.js +506 -0
  213. package/dist/components/ui/expense-detail-item.mjs +15 -0
  214. package/dist/components/ui/expense-work-details.js +1259 -0
  215. package/dist/components/ui/expense-work-details.mjs +175 -0
  216. package/dist/components/ui/field.mjs +2 -2
  217. package/dist/components/ui/file-preview-dialog.js +704 -0
  218. package/dist/components/ui/file-preview-dialog.mjs +17 -0
  219. package/dist/components/ui/financial-cards.mjs +2 -2
  220. package/dist/components/ui/financial-drawers.js +1 -1
  221. package/dist/components/ui/financial-drawers.mjs +5 -5
  222. package/dist/components/ui/financial-sections.mjs +4 -4
  223. package/dist/components/ui/form-primitives.mjs +2 -2
  224. package/dist/components/ui/frontend-signup-steps.js +1239 -0
  225. package/dist/components/ui/frontend-signup-steps.mjs +38 -0
  226. package/dist/components/ui/income-bar-chart.mjs +4 -4
  227. package/dist/components/ui/income-sources-card.js +269 -0
  228. package/dist/components/ui/income-sources-card.mjs +100 -0
  229. package/dist/components/ui/income-summary-component.js +361 -0
  230. package/dist/components/ui/income-summary-component.mjs +84 -0
  231. package/dist/components/ui/income-work-details.js +1663 -0
  232. package/dist/components/ui/income-work-details.mjs +28 -0
  233. package/dist/components/ui/incoming-outgoings-card.js +218 -0
  234. package/dist/components/ui/incoming-outgoings-card.mjs +82 -0
  235. package/dist/components/ui/interest-rate-input.js +442 -0
  236. package/dist/components/ui/interest-rate-input.mjs +90 -0
  237. package/dist/components/ui/interest-rate-section.js +337 -0
  238. package/dist/components/ui/interest-rate-section.mjs +84 -0
  239. package/dist/components/ui/interest-rate-used.js +202 -0
  240. package/dist/components/ui/interest-rate-used.mjs +62 -0
  241. package/dist/components/ui/kanban-column.js +338 -160
  242. package/dist/components/ui/kanban-column.mjs +13 -11
  243. package/dist/components/ui/loan-applicant-information.js +336 -0
  244. package/dist/components/ui/loan-applicant-information.mjs +59 -0
  245. package/dist/components/ui/loan-applicant-invite.js +319 -0
  246. package/dist/components/ui/loan-applicant-invite.mjs +68 -0
  247. package/dist/components/ui/loan-application-badge.js +236 -0
  248. package/dist/components/ui/loan-application-badge.mjs +10 -0
  249. package/dist/components/ui/loan-application-cards.js +356 -0
  250. package/dist/components/ui/loan-application-cards.mjs +110 -0
  251. package/dist/components/ui/loan-entry-shell.js +104 -0
  252. package/dist/components/ui/loan-entry-shell.mjs +8 -0
  253. package/dist/components/ui/loan-financials.js +410 -0
  254. package/dist/components/ui/loan-financials.mjs +76 -0
  255. package/dist/components/ui/loan-option-card.js +102 -0
  256. package/dist/components/ui/loan-option-card.mjs +41 -0
  257. package/dist/components/ui/loan-option-group.js +288 -0
  258. package/dist/components/ui/loan-option-group.mjs +10 -0
  259. package/dist/components/ui/loan-steps.js +1121 -0
  260. package/dist/components/ui/loan-steps.mjs +509 -0
  261. package/dist/components/ui/loan-wizard-shell.js +452 -0
  262. package/dist/components/ui/loan-wizard-shell.mjs +11 -0
  263. package/dist/components/ui/money-input-with-slider.js +210 -0
  264. package/dist/components/ui/money-input-with-slider.mjs +10 -0
  265. package/dist/components/ui/money-item-with-color-indicator.js +314 -0
  266. package/dist/components/ui/money-item-with-color-indicator.mjs +20 -0
  267. package/dist/components/ui/opportunity-card.js +235 -97
  268. package/dist/components/ui/opportunity-card.mjs +11 -9
  269. package/dist/components/ui/opportunity-edit-modals.js +1 -1
  270. package/dist/components/ui/opportunity-edit-modals.mjs +15 -15
  271. package/dist/components/ui/opportunity-summary-tab.js +1 -1
  272. package/dist/components/ui/opportunity-summary-tab.mjs +19 -19
  273. package/dist/components/ui/pagination.mjs +4 -4
  274. package/dist/components/ui/password-strength-tooltip.mjs +4 -4
  275. package/dist/components/ui/pipeline-board.js +358 -176
  276. package/dist/components/ui/pipeline-board.mjs +16 -14
  277. package/dist/components/ui/pipeline-chart.mjs +3 -3
  278. package/dist/components/ui/pipeline-dialogs.js +1 -1
  279. package/dist/components/ui/pipeline-dialogs.mjs +9 -9
  280. package/dist/components/ui/pipeline-primitives.js +75 -8
  281. package/dist/components/ui/pipeline-primitives.mjs +3 -2
  282. package/dist/components/ui/popover.mjs +3 -3
  283. package/dist/components/ui/property-asset-card.js +428 -0
  284. package/dist/components/ui/property-asset-card.mjs +156 -0
  285. package/dist/components/ui/property-cashflow-doughnut-chart.mjs +4 -4
  286. package/dist/components/ui/property-debt-equity-doughnut-chart.mjs +4 -4
  287. package/dist/components/ui/property-list-carousel.js +295 -0
  288. package/dist/components/ui/property-list-carousel.mjs +11 -0
  289. package/dist/components/ui/property-mobile-estimate-line-chart.mjs +4 -4
  290. package/dist/components/ui/property-report-dialog.js +1148 -0
  291. package/dist/components/ui/property-report-dialog.mjs +25 -0
  292. package/dist/components/ui/resource-center.js +748 -0
  293. package/dist/components/ui/resource-center.mjs +24 -0
  294. package/dist/components/ui/review-alerts-dialog.js +569 -0
  295. package/dist/components/ui/review-alerts-dialog.mjs +15 -0
  296. package/dist/components/ui/savings-goal-modal.js +1148 -0
  297. package/dist/components/ui/savings-goal-modal.mjs +160 -0
  298. package/dist/components/ui/scenario-drawer.js +791 -0
  299. package/dist/components/ui/scenario-drawer.mjs +294 -0
  300. package/dist/components/ui/scenario-item.js +256 -0
  301. package/dist/components/ui/scenario-item.mjs +11 -0
  302. package/dist/components/ui/scenario-list.js +507 -0
  303. package/dist/components/ui/scenario-list.mjs +100 -0
  304. package/dist/components/ui/select.mjs +3 -3
  305. package/dist/components/ui/share-details-dialog.js +636 -0
  306. package/dist/components/ui/share-details-dialog.mjs +19 -0
  307. package/dist/components/ui/sheet.mjs +3 -3
  308. package/dist/components/ui/sidebar-nav.mjs +5 -5
  309. package/dist/components/ui/signup-form-primitives.js +770 -0
  310. package/dist/components/ui/signup-form-primitives.mjs +25 -0
  311. package/dist/components/ui/signup-shell.js +338 -0
  312. package/dist/components/ui/signup-shell.mjs +13 -0
  313. package/dist/components/ui/stage-timeline.js +103 -33
  314. package/dist/components/ui/stage-timeline.mjs +5 -4
  315. package/dist/components/ui/submission-confirmation-card.js +284 -0
  316. package/dist/components/ui/submission-confirmation-card.mjs +62 -0
  317. package/dist/components/ui/tooltip.mjs +3 -3
  318. package/dist/components/ui/top-three-product.js +374 -0
  319. package/dist/components/ui/top-three-product.mjs +129 -0
  320. package/dist/components/ui/transactions-expense-categories-doughnut-chart.mjs +4 -4
  321. package/dist/components/ui/transactions-income-expense-bar-chart.mjs +5 -5
  322. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.mjs +4 -4
  323. package/dist/components/ui/transactions-summary-block.js +95 -0
  324. package/dist/components/ui/transactions-summary-block.mjs +34 -0
  325. package/dist/components/ui/two-fa-setup-form.mjs +3 -3
  326. package/dist/index.js +9430 -4573
  327. package/dist/index.mjs +404 -251
  328. package/dist/lib/colors.js +6 -0
  329. package/dist/lib/colors.mjs +3 -1
  330. package/dist/lib/theme-provider.mjs +2 -2
  331. package/dist/styles.css +1 -1
  332. package/package.json +366 -2
  333. package/src/components/index.tsx +223 -0
  334. package/src/components/ui/about-you-form.tsx +397 -0
  335. package/src/components/ui/account-list-carousel.tsx +87 -0
  336. package/src/components/ui/add-lead-modal.tsx +1 -1
  337. package/src/components/ui/agent-evaluation-toast.tsx +191 -0
  338. package/src/components/ui/ai-builder.tsx +3 -5
  339. package/src/components/ui/ai-conversations.tsx +1 -1
  340. package/src/components/ui/applicant-document-checklist.tsx +175 -0
  341. package/src/components/ui/applicant-expenses-section.tsx +260 -0
  342. package/src/components/ui/applicant-navigation-bar.tsx +104 -0
  343. package/src/components/ui/applicant-switcher.tsx +54 -0
  344. package/src/components/ui/application-mobile-layout.tsx +34 -0
  345. package/src/components/ui/appointment-availability-settings.tsx +115 -23
  346. package/src/components/ui/appointment-book-dialog.tsx +406 -259
  347. package/src/components/ui/appointment-calendar-view.tsx +4 -1
  348. package/src/components/ui/appointment-detail-sheet.tsx +59 -24
  349. package/src/components/ui/appointment-time-slot-picker.tsx +5 -1
  350. package/src/components/ui/asset-accordion.tsx +241 -0
  351. package/src/components/ui/assets-liabilities-side-card.tsx +157 -0
  352. package/src/components/ui/auth-page-layout.tsx +3 -3
  353. package/src/components/ui/backoffice-alert-matching-chart.tsx +320 -0
  354. package/src/components/ui/backoffice-contact-matching-chart.tsx +341 -0
  355. package/src/components/ui/backoffice-signup-steps.tsx +615 -0
  356. package/src/components/ui/bank-statement-document-table.tsx +222 -0
  357. package/src/components/ui/bank-statement-generate-dialog.tsx +435 -0
  358. package/src/components/ui/bank-statement-pdf-viewer.tsx +241 -0
  359. package/src/components/ui/banking-accounts-connect.tsx +187 -0
  360. package/src/components/ui/borrowing-capacity-atoms.tsx +228 -0
  361. package/src/components/ui/borrowing-capacity-card.tsx +155 -0
  362. package/src/components/ui/broker-info-panel.tsx +94 -0
  363. package/src/components/ui/calculator-input-item.tsx +49 -0
  364. package/src/components/ui/calculator-section.tsx +275 -0
  365. package/src/components/ui/category-edit-dialog.tsx +300 -0
  366. package/src/components/ui/connect-bank-step.tsx +379 -0
  367. package/src/components/ui/contact-alert-dialog.tsx +710 -0
  368. package/src/components/ui/create-contact-modal.tsx +237 -0
  369. package/src/components/ui/csv-import-modal.tsx +153 -0
  370. package/src/components/ui/currency-input.tsx +104 -0
  371. package/src/components/ui/dashboard-expense-categories.tsx +262 -0
  372. package/src/components/ui/dashboard-transactions-table.tsx +241 -0
  373. package/src/components/ui/debt-accordion.tsx +254 -0
  374. package/src/components/ui/delete-contact-component.tsx +87 -0
  375. package/src/components/ui/dialog.tsx +2 -2
  376. package/src/components/ui/dynamic-tabs.tsx +149 -0
  377. package/src/components/ui/editable-money-item.tsx +176 -0
  378. package/src/components/ui/expense-detail-item.tsx +216 -0
  379. package/src/components/ui/expense-work-details.tsx +229 -0
  380. package/src/components/ui/file-preview-dialog.tsx +292 -0
  381. package/src/components/ui/financial-drawers.tsx +1 -1
  382. package/src/components/ui/frontend-signup-steps.tsx +548 -0
  383. package/src/components/ui/income-sources-card.tsx +143 -0
  384. package/src/components/ui/income-summary-component.tsx +120 -0
  385. package/src/components/ui/income-work-details.tsx +429 -0
  386. package/src/components/ui/incoming-outgoings-card.tsx +111 -0
  387. package/src/components/ui/interest-rate-input.tsx +111 -0
  388. package/src/components/ui/interest-rate-section.tsx +158 -0
  389. package/src/components/ui/interest-rate-used.tsx +82 -0
  390. package/src/components/ui/kanban-column.tsx +53 -2
  391. package/src/components/ui/loan-applicant-information.tsx +64 -0
  392. package/src/components/ui/loan-applicant-invite.tsx +67 -0
  393. package/src/components/ui/loan-application-badge.tsx +70 -0
  394. package/src/components/ui/loan-application-cards.tsx +152 -0
  395. package/src/components/ui/loan-entry-shell.tsx +86 -0
  396. package/src/components/ui/loan-financials.tsx +77 -0
  397. package/src/components/ui/loan-option-card.tsx +62 -0
  398. package/src/components/ui/loan-option-group.tsx +106 -0
  399. package/src/components/ui/loan-steps.tsx +630 -0
  400. package/src/components/ui/loan-wizard-shell.tsx +235 -0
  401. package/src/components/ui/money-input-with-slider.tsx +77 -0
  402. package/src/components/ui/money-item-with-color-indicator.tsx +30 -0
  403. package/src/components/ui/opportunity-card.tsx +46 -18
  404. package/src/components/ui/pipeline-board.tsx +13 -0
  405. package/src/components/ui/pipeline-primitives.tsx +28 -0
  406. package/src/components/ui/property-asset-card.tsx +221 -0
  407. package/src/components/ui/property-list-carousel.tsx +73 -0
  408. package/src/components/ui/property-report-dialog.tsx +355 -0
  409. package/src/components/ui/resource-center.tsx +539 -0
  410. package/src/components/ui/review-alerts-dialog.tsx +163 -0
  411. package/src/components/ui/savings-goal-modal.tsx +169 -0
  412. package/src/components/ui/scenario-drawer.tsx +358 -0
  413. package/src/components/ui/scenario-item.tsx +141 -0
  414. package/src/components/ui/scenario-list.tsx +150 -0
  415. package/src/components/ui/share-details-dialog.tsx +238 -0
  416. package/src/components/ui/signup-form-primitives.tsx +212 -0
  417. package/src/components/ui/signup-shell.tsx +180 -0
  418. package/src/components/ui/stage-timeline.tsx +11 -0
  419. package/src/components/ui/submission-confirmation-card.tsx +68 -0
  420. package/src/components/ui/top-three-product.tsx +207 -0
  421. package/src/components/ui/transactions-summary-block.tsx +59 -0
  422. package/src/lib/colors.ts +12 -0
  423. package/src/lib/format-date.ts +2 -2
  424. package/src/styles/styles-css.ts +1 -1
  425. package/tsup.config.ts +77 -1
  426. package/dist/{chunk-5VOTTIXF.mjs → chunk-FRT3S72S.mjs} +3 -3
  427. package/dist/{chunk-7BTFGCFC.mjs → chunk-MUV4EGDW.mjs} +3 -3
  428. package/dist/{chunk-57ZXILTS.mjs → chunk-MXP2RX2V.mjs} +3 -3
  429. package/dist/{chunk-ZKWXDQDG.mjs → chunk-VCDGLN25.mjs} +3 -3
  430. package/dist/{chunk-FLL633WS.mjs → chunk-ZXEUBBHJ.mjs} +3 -3
@@ -0,0 +1,260 @@
1
+ import * as React from "react";
2
+ import { cn } from "@/lib/utils";
3
+ import { Button } from "@/components/ui/button";
4
+ import { formatCurrency } from "@/lib/format-currency";
5
+
6
+ export type ExpenseCategoryData = {
7
+ label: string;
8
+ color: string;
9
+ monthlyAmounts: number[];
10
+ };
11
+
12
+ export type ApplicantExpensesSectionProps = {
13
+ applicantName: string;
14
+ /** Three states: loading, access granted, access not granted. */
15
+ state: "loading" | "connected" | "pending-access";
16
+ /** Last 12 month labels (e.g. "Jan", "Feb" …). Required when state = "connected". */
17
+ monthLabels?: string[];
18
+ /** Per-category breakdown. Required when state = "connected". */
19
+ categories?: ExpenseCategoryData[];
20
+ /** Total spend over the loaded period. */
21
+ totalAmount?: number;
22
+ onConnectMore?: () => void;
23
+ onAddManually?: () => void;
24
+ onSendRequest?: () => void;
25
+ className?: string;
26
+ };
27
+
28
+ export function ApplicantExpensesSection({
29
+ applicantName,
30
+ state,
31
+ monthLabels = [],
32
+ categories = [],
33
+ totalAmount = 0,
34
+ onConnectMore,
35
+ onAddManually,
36
+ onSendRequest,
37
+ className,
38
+ }: ApplicantExpensesSectionProps) {
39
+ return (
40
+ <div className={cn("flex flex-col gap-4 font-sans", className)}>
41
+ <h3 className="text-sm font-semibold text-foreground">
42
+ {applicantName}&apos;s Expenses
43
+ </h3>
44
+
45
+ {state === "loading" && <LoadingState />}
46
+
47
+ {state === "connected" && (
48
+ <ConnectedState
49
+ monthLabels={monthLabels}
50
+ categories={categories}
51
+ totalAmount={totalAmount}
52
+ onConnectMore={onConnectMore}
53
+ onAddManually={onAddManually}
54
+ />
55
+ )}
56
+
57
+ {state === "pending-access" && (
58
+ <PendingAccessState
59
+ applicantName={applicantName}
60
+ onSendRequest={onSendRequest}
61
+ />
62
+ )}
63
+ </div>
64
+ );
65
+ }
66
+
67
+ // ─── Sub-states ───────────────────────────────────────────────────────────────
68
+
69
+ function LoadingState() {
70
+ return (
71
+ <div className="flex h-48 items-center justify-center border border-border bg-muted/30">
72
+ <div className="flex items-center gap-2 text-sm text-muted-foreground">
73
+ <SpinnerIcon className="size-4 animate-spin" />
74
+ Loading banking data…
75
+ </div>
76
+ </div>
77
+ );
78
+ }
79
+
80
+ function ConnectedState({
81
+ monthLabels,
82
+ categories,
83
+ totalAmount,
84
+ onConnectMore,
85
+ onAddManually,
86
+ }: {
87
+ monthLabels: string[];
88
+ categories: ExpenseCategoryData[];
89
+ totalAmount: number;
90
+ onConnectMore?: () => void;
91
+ onAddManually?: () => void;
92
+ }) {
93
+ const maxValue = Math.max(
94
+ ...monthLabels.map((_, mi) =>
95
+ categories.reduce((sum, cat) => sum + (cat.monthlyAmounts[mi] ?? 0), 0),
96
+ ),
97
+ 1,
98
+ );
99
+
100
+ return (
101
+ <div className="flex flex-col gap-4">
102
+ <div className="flex flex-wrap items-start justify-between gap-4">
103
+ <div className="flex flex-col gap-0.5">
104
+ <span className="text-title-medium font-semibold text-foreground">
105
+ {formatCurrency(totalAmount)}
106
+ </span>
107
+ <span className="text-xs text-muted-foreground">
108
+ Total latest 12 months
109
+ </span>
110
+ </div>
111
+ <div className="flex flex-col gap-2">
112
+ <Button size="sm" onClick={onConnectMore}>
113
+ Connect More Accounts
114
+ </Button>
115
+ {onAddManually && (
116
+ <Button size="sm" variant="outline" onClick={onAddManually}>
117
+ Add Manually
118
+ </Button>
119
+ )}
120
+ </div>
121
+ </div>
122
+
123
+ {/* Mini stacked bar chart */}
124
+ {monthLabels.length > 0 && categories.length > 0 && (
125
+ <div className="overflow-x-auto">
126
+ <div className="flex min-w-0 items-end gap-1">
127
+ {monthLabels.map((month, mi) => {
128
+ const colTotal = categories.reduce(
129
+ (sum, cat) => sum + (cat.monthlyAmounts[mi] ?? 0),
130
+ 0,
131
+ );
132
+ const heightPct = (colTotal / maxValue) * 100;
133
+ return (
134
+ <div
135
+ key={month}
136
+ className="flex flex-1 flex-col items-center gap-1"
137
+ >
138
+ <div
139
+ className="flex w-full flex-col-reverse overflow-hidden"
140
+ style={{ height: 80 }}
141
+ title={`${month}: ${formatCurrency(colTotal)}`}
142
+ >
143
+ <div
144
+ className="flex w-full flex-col-reverse"
145
+ style={{ height: `${heightPct}%` }}
146
+ >
147
+ {categories.map((cat) => {
148
+ const segPct =
149
+ colTotal > 0
150
+ ? ((cat.monthlyAmounts[mi] ?? 0) / colTotal) * 100
151
+ : 0;
152
+ return (
153
+ <div
154
+ key={cat.label}
155
+ style={{
156
+ height: `${segPct}%`,
157
+ backgroundColor: cat.color,
158
+ }}
159
+ />
160
+ );
161
+ })}
162
+ </div>
163
+ </div>
164
+ <span className="text-[10px] text-muted-foreground">
165
+ {month}
166
+ </span>
167
+ </div>
168
+ );
169
+ })}
170
+ </div>
171
+ </div>
172
+ )}
173
+
174
+ {/* Legend */}
175
+ {categories.length > 0 && (
176
+ <div className="flex flex-wrap gap-3">
177
+ {categories.map((cat) => (
178
+ <div key={cat.label} className="flex items-center gap-1.5">
179
+ <div
180
+ className="size-2.5 shrink-0"
181
+ style={{ backgroundColor: cat.color }}
182
+ />
183
+ <span className="text-xs text-muted-foreground">{cat.label}</span>
184
+ </div>
185
+ ))}
186
+ </div>
187
+ )}
188
+ </div>
189
+ );
190
+ }
191
+
192
+ function PendingAccessState({
193
+ applicantName,
194
+ onSendRequest,
195
+ }: {
196
+ applicantName: string;
197
+ onSendRequest?: () => void;
198
+ }) {
199
+ return (
200
+ <div className="flex flex-col items-center gap-4 border border-border py-10 text-center">
201
+ <LockIcon className="size-8 text-muted-foreground" />
202
+ <div className="flex flex-col gap-1">
203
+ <p className="text-sm font-medium text-foreground">
204
+ Requires access to banking data
205
+ </p>
206
+ <p className="text-xs text-muted-foreground">
207
+ Send {applicantName} an invitation to connect their bank accounts.
208
+ </p>
209
+ </div>
210
+ <Button onClick={onSendRequest}>Send request to {applicantName}</Button>
211
+ </div>
212
+ );
213
+ }
214
+
215
+ // ─── Icons ────────────────────────────────────────────────────────────────────
216
+
217
+ function SpinnerIcon({ className }: { className?: string }) {
218
+ return (
219
+ <svg
220
+ xmlns="http://www.w3.org/2000/svg"
221
+ fill="none"
222
+ viewBox="0 0 24 24"
223
+ className={className}
224
+ aria-hidden="true"
225
+ >
226
+ <circle
227
+ className="opacity-25"
228
+ cx="12"
229
+ cy="12"
230
+ r="10"
231
+ stroke="currentColor"
232
+ strokeWidth="4"
233
+ />
234
+ <path
235
+ className="opacity-75"
236
+ fill="currentColor"
237
+ d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
238
+ />
239
+ </svg>
240
+ );
241
+ }
242
+
243
+ function LockIcon({ className }: { className?: string }) {
244
+ return (
245
+ <svg
246
+ xmlns="http://www.w3.org/2000/svg"
247
+ viewBox="0 0 24 24"
248
+ fill="none"
249
+ stroke="currentColor"
250
+ strokeWidth={2}
251
+ strokeLinecap="round"
252
+ strokeLinejoin="round"
253
+ className={className}
254
+ aria-hidden="true"
255
+ >
256
+ <rect x="3" y="11" width="18" height="11" rx="0" />
257
+ <path d="M7 11V7a5 5 0 0 1 10 0v4" />
258
+ </svg>
259
+ );
260
+ }
@@ -0,0 +1,104 @@
1
+ import * as React from "react";
2
+ import { cn } from "@/lib/utils";
3
+ import { Button } from "@/components/ui/button";
4
+
5
+ export type ApplicantNavigationBarApplicant = {
6
+ name: string;
7
+ };
8
+
9
+ export type ApplicantNavigationBarProps = {
10
+ applicants: ApplicantNavigationBarApplicant[];
11
+ currentIndex: number;
12
+ /** Ordered list of applicant indices to navigate between. */
13
+ displayOrder?: number[];
14
+ onPrev?: () => void;
15
+ onNext?: () => void;
16
+ /** Called when there is no next applicant (last in order). */
17
+ onSaveAndNext?: () => void;
18
+ saveLabel?: string;
19
+ className?: string;
20
+ };
21
+
22
+ export function ApplicantNavigationBar({
23
+ applicants,
24
+ currentIndex,
25
+ displayOrder,
26
+ onPrev,
27
+ onNext,
28
+ onSaveAndNext,
29
+ saveLabel = "Save & Next",
30
+ className,
31
+ }: ApplicantNavigationBarProps) {
32
+ const order = displayOrder ?? applicants.map((_, i) => i);
33
+ const position = order.indexOf(currentIndex);
34
+ const pos = position >= 0 ? position : 0;
35
+ const isFirst = pos === 0;
36
+ const isLast = pos === order.length - 1;
37
+ const hasMultiple = applicants.length > 1;
38
+
39
+ return (
40
+ <div
41
+ className={cn(
42
+ "flex items-center justify-between pt-6 font-sans",
43
+ className,
44
+ )}
45
+ >
46
+ {hasMultiple && !isFirst ? (
47
+ <Button variant="outline" onClick={onPrev}>
48
+ <ChevronLeftIcon className="mr-1 size-4" />
49
+ Previous
50
+ </Button>
51
+ ) : (
52
+ <span />
53
+ )}
54
+
55
+ {hasMultiple && !isLast ? (
56
+ <Button variant="outline" onClick={onNext}>
57
+ Next
58
+ <ChevronRightIcon className="ml-1 size-4" />
59
+ </Button>
60
+ ) : (
61
+ <Button onClick={onSaveAndNext}>
62
+ {saveLabel}
63
+ <ChevronRightIcon className="ml-1 size-4" />
64
+ </Button>
65
+ )}
66
+ </div>
67
+ );
68
+ }
69
+
70
+ function ChevronLeftIcon({ className }: { className?: string }) {
71
+ return (
72
+ <svg
73
+ xmlns="http://www.w3.org/2000/svg"
74
+ viewBox="0 0 24 24"
75
+ fill="none"
76
+ stroke="currentColor"
77
+ strokeWidth={2}
78
+ strokeLinecap="round"
79
+ strokeLinejoin="round"
80
+ className={className}
81
+ aria-hidden="true"
82
+ >
83
+ <path d="m15 18-6-6 6-6" />
84
+ </svg>
85
+ );
86
+ }
87
+
88
+ function ChevronRightIcon({ className }: { className?: string }) {
89
+ return (
90
+ <svg
91
+ xmlns="http://www.w3.org/2000/svg"
92
+ viewBox="0 0 24 24"
93
+ fill="none"
94
+ stroke="currentColor"
95
+ strokeWidth={2}
96
+ strokeLinecap="round"
97
+ strokeLinejoin="round"
98
+ className={className}
99
+ aria-hidden="true"
100
+ >
101
+ <path d="m9 18 6-6-6-6" />
102
+ </svg>
103
+ );
104
+ }
@@ -0,0 +1,54 @@
1
+ import React from "react";
2
+ import { cn } from "@/lib/utils";
3
+ import { Button } from "@/components/ui/button";
4
+
5
+ /**
6
+ * Segmented toggle bar for switching between the main applicant and
7
+ * co-applicant(s) in the loan wizard. Returns null when fewer than 2
8
+ * applicants are present.
9
+ */
10
+
11
+ export type ApplicantSwitcherApplicant = {
12
+ name: string;
13
+ };
14
+
15
+ export type ApplicantSwitcherProps = {
16
+ applicants: ApplicantSwitcherApplicant[];
17
+ selectedIndex: number;
18
+ onSelect: (index: number) => void;
19
+ className?: string;
20
+ };
21
+
22
+ export function ApplicantSwitcher({
23
+ applicants,
24
+ selectedIndex,
25
+ onSelect,
26
+ className,
27
+ }: ApplicantSwitcherProps) {
28
+ if (!applicants || applicants.length <= 1) return null;
29
+
30
+ return (
31
+ <div
32
+ className={cn("flex w-fit items-center", className)}
33
+ role="group"
34
+ aria-label="Select applicant"
35
+ >
36
+ {applicants.map((applicant, index) => (
37
+ <Button
38
+ key={index}
39
+ type="button"
40
+ variant={selectedIndex === index ? "default" : "outline"}
41
+ onClick={() => onSelect(index)}
42
+ aria-pressed={selectedIndex === index}
43
+ className={cn(
44
+ "rounded-none",
45
+ // Remove left border on non-first items to create a joined look
46
+ index > 0 && "-ml-px",
47
+ )}
48
+ >
49
+ {applicant.name}
50
+ </Button>
51
+ ))}
52
+ </div>
53
+ );
54
+ }
@@ -0,0 +1,34 @@
1
+ import React from "react";
2
+ import { cn } from "@/lib/utils";
3
+
4
+ /**
5
+ * Outer responsive shell for multi-step application flows (e.g. Loan Application).
6
+ *
7
+ * - Mobile (< md): full-screen, no extra padding — content fills the viewport.
8
+ * - Desktop (≥ md): wraps content in a centered max-width card so the flow
9
+ * doesn't stretch across a wide screen.
10
+ *
11
+ * Compose inside this wrapper, then place OnboardingLayout (or similar) as the child.
12
+ */
13
+ export interface ApplicationMobileLayoutProps {
14
+ children: React.ReactNode;
15
+ className?: string;
16
+ }
17
+
18
+ export function ApplicationMobileLayout({
19
+ children,
20
+ className,
21
+ }: ApplicationMobileLayoutProps) {
22
+ return (
23
+ <div
24
+ className={cn(
25
+ "min-h-screen bg-background font-sans",
26
+ // On desktop, center and cap the width so it doesn't span the full screen
27
+ "md:flex md:items-start md:justify-center md:py-8",
28
+ className,
29
+ )}
30
+ >
31
+ <div className="w-full md:max-w-2xl">{children}</div>
32
+ </div>
33
+ );
34
+ }
@@ -44,6 +44,11 @@ export interface AppointmentAvailabilityPrefs {
44
44
  maxSlotsPerDay: string;
45
45
  /** IANA timezone identifier — e.g. "Australia/Sydney" */
46
46
  timezone: string;
47
+ /**
48
+ * Online meeting platform brokers require clients to use.
49
+ * "any" means the client can choose between Google Meet and Microsoft Teams.
50
+ */
51
+ defaultMeetingPlatform?: "google-meet" | "microsoft-teams" | "any";
47
52
  }
48
53
 
49
54
  export interface AppointmentBlockedDate {
@@ -117,6 +122,44 @@ export const TIMEZONE_OPTIONS: { value: string; label: string }[] = [
117
122
  { value: "UTC", label: "UTC" },
118
123
  ];
119
124
 
125
+ export const MEETING_PLATFORM_OPTIONS: {
126
+ value: "google-meet" | "microsoft-teams" | "any";
127
+ label: string;
128
+ }[] = [
129
+ { value: "google-meet", label: "Google Meet" },
130
+ { value: "microsoft-teams", label: "Microsoft Teams" },
131
+ { value: "any", label: "Let client choose" },
132
+ ];
133
+
134
+ const MEETING_DURATION_OPTIONS: { value: string; label: string }[] = [
135
+ { value: "15", label: "15 minutes" },
136
+ { value: "30", label: "30 minutes" },
137
+ { value: "45", label: "45 minutes" },
138
+ { value: "60", label: "60 minutes" },
139
+ { value: "90", label: "90 minutes" },
140
+ ];
141
+
142
+ const SCHEDULING_BUFFER_OPTIONS: { value: string; label: string }[] = [
143
+ { value: "0", label: "No buffer" },
144
+ { value: "5", label: "5 minutes" },
145
+ { value: "10", label: "10 minutes" },
146
+ { value: "15", label: "15 minutes" },
147
+ { value: "30", label: "30 minutes" },
148
+ ];
149
+
150
+ const MAX_SLOTS_OPTIONS: { value: string; label: string }[] = [
151
+ { value: "2", label: "2 per day" },
152
+ { value: "4", label: "4 per day" },
153
+ { value: "6", label: "6 per day" },
154
+ { value: "8", label: "8 per day" },
155
+ { value: "10", label: "10 per day" },
156
+ { value: "unlimited", label: "Unlimited" },
157
+ ];
158
+
159
+ /** Map a Base UI SelectValue `v` to its display label from an options array. */
160
+ const selectLabel = (opts: { value: string; label: string }[], v: unknown) =>
161
+ opts.find((o) => o.value === String(v))?.label ?? String(v ?? "");
162
+
120
163
  // 30-min increments from 06:00 to 21:30
121
164
  const TIME_OPTIONS: { value: string; label: string }[] = (() => {
122
165
  const opts: { value: string; label: string }[] = [];
@@ -249,7 +292,7 @@ function AddTimeOffDialog({
249
292
 
250
293
  return (
251
294
  <Dialog open={open} onOpenChange={onOpenChange}>
252
- <DialogContent size="auto" minWidth="26rem" align="top">
295
+ <DialogContent size="auto" minWidth="26rem">
253
296
  <DialogHeader>
254
297
  <DialogTitle>Add time off</DialogTitle>
255
298
  <DialogDescription>
@@ -349,6 +392,9 @@ export function AppointmentAvailabilitySettings({
349
392
  const [timezone, setTimezone] = React.useState(
350
393
  prefsProp?.timezone ?? "Australia/Sydney",
351
394
  );
395
+ const [defaultMeetingPlatform, setDefaultMeetingPlatform] = React.useState<
396
+ "google-meet" | "microsoft-teams" | "any"
397
+ >(prefsProp?.defaultMeetingPlatform ?? "any");
352
398
 
353
399
  const [timeOffEntries, setTimeOffEntries] = React.useState<TimeOffEntry[]>(
354
400
  () => {
@@ -384,8 +430,20 @@ export function AppointmentAvailabilitySettings({
384
430
  // ---------------------------------------------------------------------------
385
431
 
386
432
  const currentPrefs = React.useMemo(
387
- () => ({ meetingDuration, schedulingBuffer, maxSlotsPerDay, timezone }),
388
- [meetingDuration, schedulingBuffer, maxSlotsPerDay, timezone],
433
+ () => ({
434
+ meetingDuration,
435
+ schedulingBuffer,
436
+ maxSlotsPerDay,
437
+ timezone,
438
+ defaultMeetingPlatform,
439
+ }),
440
+ [
441
+ meetingDuration,
442
+ schedulingBuffer,
443
+ maxSlotsPerDay,
444
+ timezone,
445
+ defaultMeetingPlatform,
446
+ ],
389
447
  );
390
448
 
391
449
  const saveGuard = React.useRef(false);
@@ -535,14 +593,16 @@ export function AppointmentAvailabilitySettings({
535
593
  onValueChange={(v) => setMeetingDuration(v as string)}
536
594
  >
537
595
  <SelectTrigger className="w-40">
538
- <SelectValue />
596
+ <SelectValue>
597
+ {(v) => selectLabel(MEETING_DURATION_OPTIONS, v)}
598
+ </SelectValue>
539
599
  </SelectTrigger>
540
600
  <SelectContent>
541
- <SelectItem value="15">15 minutes</SelectItem>
542
- <SelectItem value="30">30 minutes</SelectItem>
543
- <SelectItem value="45">45 minutes</SelectItem>
544
- <SelectItem value="60">60 minutes</SelectItem>
545
- <SelectItem value="90">90 minutes</SelectItem>
601
+ {MEETING_DURATION_OPTIONS.map((opt) => (
602
+ <SelectItem key={opt.value} value={opt.value}>
603
+ {opt.label}
604
+ </SelectItem>
605
+ ))}
546
606
  </SelectContent>
547
607
  </Select>
548
608
  </PrefRow>
@@ -556,14 +616,16 @@ export function AppointmentAvailabilitySettings({
556
616
  onValueChange={(v) => setSchedulingBuffer(v as string)}
557
617
  >
558
618
  <SelectTrigger className="w-40">
559
- <SelectValue />
619
+ <SelectValue>
620
+ {(v) => selectLabel(SCHEDULING_BUFFER_OPTIONS, v)}
621
+ </SelectValue>
560
622
  </SelectTrigger>
561
623
  <SelectContent>
562
- <SelectItem value="0">No buffer</SelectItem>
563
- <SelectItem value="5">5 minutes</SelectItem>
564
- <SelectItem value="10">10 minutes</SelectItem>
565
- <SelectItem value="15">15 minutes</SelectItem>
566
- <SelectItem value="30">30 minutes</SelectItem>
624
+ {SCHEDULING_BUFFER_OPTIONS.map((opt) => (
625
+ <SelectItem key={opt.value} value={opt.value}>
626
+ {opt.label}
627
+ </SelectItem>
628
+ ))}
567
629
  </SelectContent>
568
630
  </Select>
569
631
  </PrefRow>
@@ -577,15 +639,16 @@ export function AppointmentAvailabilitySettings({
577
639
  onValueChange={(v) => setMaxSlotsPerDay(v as string)}
578
640
  >
579
641
  <SelectTrigger className="w-40">
580
- <SelectValue />
642
+ <SelectValue>
643
+ {(v) => selectLabel(MAX_SLOTS_OPTIONS, v)}
644
+ </SelectValue>
581
645
  </SelectTrigger>
582
646
  <SelectContent>
583
- <SelectItem value="2">2 per day</SelectItem>
584
- <SelectItem value="4">4 per day</SelectItem>
585
- <SelectItem value="6">6 per day</SelectItem>
586
- <SelectItem value="8">8 per day</SelectItem>
587
- <SelectItem value="10">10 per day</SelectItem>
588
- <SelectItem value="unlimited">Unlimited</SelectItem>
647
+ {MAX_SLOTS_OPTIONS.map((opt) => (
648
+ <SelectItem key={opt.value} value={opt.value}>
649
+ {opt.label}
650
+ </SelectItem>
651
+ ))}
589
652
  </SelectContent>
590
653
  </Select>
591
654
  </PrefRow>
@@ -599,7 +662,9 @@ export function AppointmentAvailabilitySettings({
599
662
  onValueChange={(v) => setTimezone(v as string)}
600
663
  >
601
664
  <SelectTrigger className="w-56">
602
- <SelectValue />
665
+ <SelectValue>
666
+ {(v) => selectLabel(TIMEZONE_OPTIONS, v)}
667
+ </SelectValue>
603
668
  </SelectTrigger>
604
669
  <SelectContent>
605
670
  {TIMEZONE_OPTIONS.map((opt) => (
@@ -610,6 +675,33 @@ export function AppointmentAvailabilitySettings({
610
675
  </SelectContent>
611
676
  </Select>
612
677
  </PrefRow>
678
+
679
+ <PrefRow
680
+ label="Default Meeting Platform"
681
+ description="Online meeting platform clients must use when booking"
682
+ >
683
+ <Select
684
+ value={defaultMeetingPlatform}
685
+ onValueChange={(v) =>
686
+ setDefaultMeetingPlatform(
687
+ v as "google-meet" | "microsoft-teams" | "any",
688
+ )
689
+ }
690
+ >
691
+ <SelectTrigger className="w-48">
692
+ <SelectValue>
693
+ {(v) => selectLabel(MEETING_PLATFORM_OPTIONS, v)}
694
+ </SelectValue>
695
+ </SelectTrigger>
696
+ <SelectContent>
697
+ {MEETING_PLATFORM_OPTIONS.map((opt) => (
698
+ <SelectItem key={opt.value} value={opt.value}>
699
+ {opt.label}
700
+ </SelectItem>
701
+ ))}
702
+ </SelectContent>
703
+ </Select>
704
+ </PrefRow>
613
705
  </div>
614
706
  </TabsContent>
615
707