@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,120 @@
1
+ import React from "react";
2
+ import { cn } from "@/lib/utils";
3
+ import { formatCurrency } from "@/lib/format-currency";
4
+ import { Button } from "@/components/ui/button";
5
+ import { Badge } from "@/components/ui/badge";
6
+
7
+ /**
8
+ * Displays a read-only list of income entries with edit/delete actions and an
9
+ * "Add income" CTA. Extracted from the loan application income tab.
10
+ * Consumers pre-calculate per-year totals before passing them in.
11
+ */
12
+
13
+ export type IncomeSummaryItem = {
14
+ /** Primary label — e.g. "Developer at Acme Corp" or "Rental Income" */
15
+ title: string;
16
+ /** Annualised income in whole dollars */
17
+ amountPerYear: number;
18
+ /** Optional duration string — "Employed for 3.5 yrs" */
19
+ employmentDuration?: string;
20
+ /** Small tag chips — employment status, basis, type */
21
+ statusTags?: string[];
22
+ /** Non-PAYG income source label */
23
+ source?: string;
24
+ };
25
+
26
+ export type IncomeSummaryComponentProps = {
27
+ incomes: IncomeSummaryItem[];
28
+ onAdd: () => void;
29
+ onEdit: (index: number) => void;
30
+ onDelete: (index: number) => void;
31
+ className?: string;
32
+ };
33
+
34
+ export function IncomeSummaryComponent({
35
+ incomes,
36
+ onAdd,
37
+ onEdit,
38
+ onDelete,
39
+ className,
40
+ }: IncomeSummaryComponentProps) {
41
+ if (!incomes.length) {
42
+ return (
43
+ <div className={cn("flex flex-col gap-4", className)}>
44
+ <p className="text-sm text-muted-foreground">No incomes added yet.</p>
45
+ <Button type="button" variant="outline" onClick={onAdd}>
46
+ + Add an income
47
+ </Button>
48
+ </div>
49
+ );
50
+ }
51
+
52
+ return (
53
+ <div className={cn("flex flex-col gap-4", className)}>
54
+ <div className="flex flex-col gap-3">
55
+ {incomes.map((income, index) => (
56
+ <div
57
+ key={index}
58
+ className="flex flex-col gap-2 border border-border p-4"
59
+ >
60
+ {/* Title row + actions */}
61
+ <div className="flex items-center justify-between gap-2">
62
+ <span className="text-base font-semibold">{income.title}</span>
63
+ <div className="flex gap-2">
64
+ <Button
65
+ type="button"
66
+ variant="outline"
67
+ size="sm"
68
+ onClick={() => onEdit(index)}
69
+ >
70
+ Edit
71
+ </Button>
72
+ <Button
73
+ type="button"
74
+ variant="outline"
75
+ size="sm"
76
+ onClick={() => onDelete(index)}
77
+ className="border-destructive text-destructive hover:bg-destructive/10"
78
+ >
79
+ Delete
80
+ </Button>
81
+ </div>
82
+ </div>
83
+
84
+ {/* Amount + duration */}
85
+ <div className="flex items-center justify-between text-sm">
86
+ <span>{formatCurrency(income.amountPerYear)} Per Year</span>
87
+ {income.employmentDuration && (
88
+ <span className="text-muted-foreground">
89
+ {income.employmentDuration}
90
+ </span>
91
+ )}
92
+ </div>
93
+
94
+ {/* Status tags */}
95
+ {income.statusTags && income.statusTags.length > 0 && (
96
+ <div className="flex flex-wrap gap-2">
97
+ {income.statusTags.map((tag) => (
98
+ <Badge key={tag} variant="secondary">
99
+ {tag}
100
+ </Badge>
101
+ ))}
102
+ </div>
103
+ )}
104
+
105
+ {/* Non-PAYG source */}
106
+ {income.source && (
107
+ <span className="text-sm text-muted-foreground">
108
+ Source: {income.source}
109
+ </span>
110
+ )}
111
+ </div>
112
+ ))}
113
+ </div>
114
+
115
+ <Button type="button" variant="outline" onClick={onAdd}>
116
+ + Add an income
117
+ </Button>
118
+ </div>
119
+ );
120
+ }
@@ -0,0 +1,429 @@
1
+ import * as React from "react";
2
+ import { cn } from "@/lib/utils";
3
+ import { Button } from "@/components/ui/button";
4
+ import { Card, CardContent } from "@/components/ui/card";
5
+ import { Input } from "@/components/ui/input";
6
+ import { Checkbox } from "@/components/ui/checkbox";
7
+ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
8
+ import { LoanOptionGroup } from "@/components/ui/loan-option-group";
9
+ import {
10
+ CurrencyInputWithSlider,
11
+ AddressAutocomplete,
12
+ } from "@/components/ui/form-primitives";
13
+ import {
14
+ Accordion,
15
+ AccordionItem,
16
+ AccordionTrigger,
17
+ AccordionContent,
18
+ } from "@/components/ui/accordion";
19
+ import { IncomeBarChart } from "@/components/ui/income-bar-chart";
20
+ import type { IncomeBarChartData } from "@/components/ui/income-bar-chart";
21
+ import { formatCurrency } from "@/lib/format-currency";
22
+
23
+ // ─── Constants ────────────────────────────────────────────────────────────────
24
+
25
+ const EMPLOYMENT_TYPE_OPTIONS = [
26
+ { value: "payg", label: "PAYG" },
27
+ { value: "self-employed", label: "Self Employed" },
28
+ { value: "unemployed", label: "Unemployed" },
29
+ { value: "retired", label: "Retired" },
30
+ ];
31
+
32
+ const EMPLOYMENT_STATUS_OPTIONS = [
33
+ { value: "primary", label: "Primary" },
34
+ { value: "secondary", label: "Secondary" },
35
+ ];
36
+
37
+ const EMPLOYMENT_BASIS_OPTIONS = [
38
+ { value: "contract", label: "Contract" },
39
+ { value: "temporary", label: "Temporary" },
40
+ { value: "casual", label: "Casual" },
41
+ ];
42
+
43
+ const INCOME_FREQUENCY_OPTIONS = [
44
+ { value: "monthly", label: "Monthly" },
45
+ { value: "weekly", label: "Weekly" },
46
+ ];
47
+
48
+ // ─── Types ────────────────────────────────────────────────────────────────────
49
+
50
+ export type IncomeEmploymentType =
51
+ | "payg"
52
+ | "self-employed"
53
+ | "unemployed"
54
+ | "retired";
55
+
56
+ export type IncomeEmploymentStatus = "primary" | "secondary";
57
+
58
+ export type IncomeEmploymentBasis =
59
+ | "contract"
60
+ | "temporary"
61
+ | "casual"
62
+ | "full-time"
63
+ | "part-time";
64
+
65
+ export type IncomeFrequency = "monthly" | "weekly";
66
+
67
+ export type IncomeCompanyType = "public" | "private";
68
+
69
+ export type IncomeWorkSource = {
70
+ id: string;
71
+ /** Accordion header label — defaults to "Main Income Source" */
72
+ label?: string;
73
+ employmentType?: IncomeEmploymentType;
74
+ employmentStatus?: IncomeEmploymentStatus;
75
+ employmentBasis?: IncomeEmploymentBasis;
76
+ jobTitle?: string;
77
+ startDate?: string;
78
+ /** Whether still in this position — when false, endDate is required */
79
+ stillInPosition?: boolean;
80
+ endDate?: string;
81
+ companyName?: string;
82
+ companyAddress?: string;
83
+ incomeAmount?: number;
84
+ incomeFrequency?: IncomeFrequency;
85
+ companyType?: IncomeCompanyType;
86
+ };
87
+
88
+ export type IncomeWorkDetailsProps = {
89
+ /** Rendered as "{applicantName} Income" in the heading */
90
+ applicantName: string;
91
+ /** Total from Open Banking — shown in summary card above the chart */
92
+ totalIncome?: number;
93
+ /** Monthly income data for the IncomeBarChart */
94
+ incomeData?: IncomeBarChartData | null;
95
+ /** Work Details accordion sources */
96
+ sources: IncomeWorkSource[];
97
+ onSourceChange?: (id: string, updates: Partial<IncomeWorkSource>) => void;
98
+ onAddSource?: () => void;
99
+ /** "Add More Account +" button in the summary card */
100
+ onConnectMore?: () => void;
101
+ className?: string;
102
+ };
103
+
104
+ // ─── Income source form ───────────────────────────────────────────────────────
105
+
106
+ function IncomeSourceForm({
107
+ source,
108
+ onChange,
109
+ }: {
110
+ source: IncomeWorkSource;
111
+ onChange: (updates: Partial<IncomeWorkSource>) => void;
112
+ }) {
113
+ return (
114
+ <div className="flex flex-col gap-4 pt-2">
115
+ {/* Employment type */}
116
+ <LoanOptionGroup
117
+ options={EMPLOYMENT_TYPE_OPTIONS}
118
+ value={source.employmentType ?? ""}
119
+ onChange={(v) => {
120
+ if (typeof v === "string")
121
+ onChange({ employmentType: v as IncomeEmploymentType });
122
+ }}
123
+ />
124
+
125
+ {/* Employment Status */}
126
+ <LoanOptionGroup
127
+ title="Employment Status"
128
+ options={EMPLOYMENT_STATUS_OPTIONS}
129
+ value={source.employmentStatus ?? ""}
130
+ onChange={(v) => {
131
+ if (typeof v === "string")
132
+ onChange({ employmentStatus: v as IncomeEmploymentStatus });
133
+ }}
134
+ />
135
+
136
+ {/* Employment Type (basis) */}
137
+ <LoanOptionGroup
138
+ title="Employment Type"
139
+ options={EMPLOYMENT_BASIS_OPTIONS}
140
+ value={source.employmentBasis ?? ""}
141
+ onChange={(v) => {
142
+ if (typeof v === "string")
143
+ onChange({ employmentBasis: v as IncomeEmploymentBasis });
144
+ }}
145
+ />
146
+
147
+ {/* Job Title */}
148
+ <div className="flex flex-col gap-1.5">
149
+ <label className="text-label-small text-muted-foreground">
150
+ Job Title
151
+ </label>
152
+ <Input
153
+ value={source.jobTitle ?? ""}
154
+ onChange={(e) => onChange({ jobTitle: e.target.value })}
155
+ placeholder="e.g. Software Engineer"
156
+ />
157
+ </div>
158
+
159
+ {/* Start Date + optional End Date (shown side-by-side when not still in position) */}
160
+ <div
161
+ className={
162
+ source.stillInPosition === false
163
+ ? "grid grid-cols-2 gap-3"
164
+ : undefined
165
+ }
166
+ >
167
+ <div className="flex flex-col gap-1.5">
168
+ <label className="text-label-small text-muted-foreground">
169
+ Start Date
170
+ </label>
171
+ <Input
172
+ type="date"
173
+ value={source.startDate ?? ""}
174
+ onChange={(e) => onChange({ startDate: e.target.value })}
175
+ />
176
+ </div>
177
+ {source.stillInPosition === false && (
178
+ <div className="flex flex-col gap-1.5">
179
+ <label className="text-label-small text-muted-foreground">
180
+ End Date
181
+ </label>
182
+ <Input
183
+ type="date"
184
+ value={source.endDate ?? ""}
185
+ onChange={(e) => onChange({ endDate: e.target.value })}
186
+ />
187
+ </div>
188
+ )}
189
+ </div>
190
+
191
+ {/* Still in position checkbox */}
192
+ <div className="flex items-center gap-2">
193
+ <Checkbox
194
+ id={`${source.id}-still-in-position`}
195
+ checked={source.stillInPosition ?? true}
196
+ onCheckedChange={(checked) =>
197
+ onChange({ stillInPosition: checked === true })
198
+ }
199
+ />
200
+ <label
201
+ htmlFor={`${source.id}-still-in-position`}
202
+ className="text-body-small cursor-pointer"
203
+ >
204
+ Still in position
205
+ </label>
206
+ </div>
207
+
208
+ {/* Company Name */}
209
+ <div className="flex flex-col gap-1.5">
210
+ <label className="text-label-small text-muted-foreground">
211
+ Company Name
212
+ </label>
213
+ <Input
214
+ value={source.companyName ?? ""}
215
+ onChange={(e) => onChange({ companyName: e.target.value })}
216
+ placeholder="e.g. Acme Corporation"
217
+ />
218
+ </div>
219
+
220
+ {/* Company Address — autocomplete */}
221
+ <div className="flex flex-col gap-1.5">
222
+ <label className="text-label-small text-muted-foreground">
223
+ Company Address
224
+ </label>
225
+ <AddressAutocomplete
226
+ value={source.companyAddress ?? ""}
227
+ onValueChange={(v) => onChange({ companyAddress: v })}
228
+ />
229
+ </div>
230
+
231
+ {/* Income Amount + Frequency — input/slider left, toggle right */}
232
+ <div className="flex flex-col gap-1.5">
233
+ <label className="text-label-small text-muted-foreground">
234
+ Income Amount
235
+ </label>
236
+ <div className="flex items-start gap-3">
237
+ <CurrencyInputWithSlider
238
+ className="flex-1"
239
+ value={source.incomeAmount ?? 0}
240
+ min={0}
241
+ max={50000}
242
+ step={100}
243
+ onValueChange={(v) => onChange({ incomeAmount: v })}
244
+ />
245
+ <LoanOptionGroup
246
+ className="shrink-0"
247
+ options={INCOME_FREQUENCY_OPTIONS}
248
+ value={source.incomeFrequency ?? ""}
249
+ onChange={(v) => {
250
+ if (typeof v === "string")
251
+ onChange({ incomeFrequency: v as IncomeFrequency });
252
+ }}
253
+ />
254
+ </div>
255
+ </div>
256
+
257
+ {/* Type of Company */}
258
+ <div className="flex flex-col gap-2">
259
+ <span className="text-label-small text-muted-foreground">
260
+ Type of Company
261
+ </span>
262
+ <RadioGroup
263
+ value={source.companyType}
264
+ onValueChange={(v) =>
265
+ onChange({ companyType: v as IncomeCompanyType })
266
+ }
267
+ className="flex flex-row gap-4"
268
+ >
269
+ <div className="flex items-center gap-2">
270
+ <RadioGroupItem value="public" id={`${source.id}-public`} />
271
+ <label
272
+ htmlFor={`${source.id}-public`}
273
+ className="text-body-small cursor-pointer"
274
+ >
275
+ Public
276
+ </label>
277
+ </div>
278
+ <div className="flex items-center gap-2">
279
+ <RadioGroupItem value="private" id={`${source.id}-private`} />
280
+ <label
281
+ htmlFor={`${source.id}-private`}
282
+ className="text-body-small cursor-pointer"
283
+ >
284
+ Private
285
+ </label>
286
+ </div>
287
+ </RadioGroup>
288
+ </div>
289
+ </div>
290
+ );
291
+ }
292
+
293
+ // ─── Component ────────────────────────────────────────────────────────────────
294
+
295
+ /**
296
+ * IncomeWorkDetails — Income section of the loan application wizard.
297
+ *
298
+ * Shows:
299
+ * 1. "{applicantName} Income" heading
300
+ * 2. Open Banking summary card — total, mini bar chart, "Add More Account +"
301
+ * 3. Income Sources — "Total Income" indicator bar
302
+ * 4. Work Details — accordion of employment source forms
303
+ *
304
+ * Figma: WealthX-Backoffice---Mobile-App — node 19308:53126
305
+ */
306
+ export function IncomeWorkDetails({
307
+ applicantName,
308
+ totalIncome,
309
+ incomeData,
310
+ sources,
311
+ onSourceChange,
312
+ onAddSource,
313
+ onConnectMore,
314
+ className,
315
+ }: IncomeWorkDetailsProps) {
316
+ const [openItems, setOpenItems] = React.useState<string[]>(
317
+ sources.length > 0 ? [sources[0].id] : [],
318
+ );
319
+
320
+ // Auto-open any source that was added after initial render
321
+ React.useEffect(() => {
322
+ setOpenItems((current) => {
323
+ const currentSet = new Set(current);
324
+ const newIds = sources
325
+ .map((s) => s.id)
326
+ .filter((id) => !currentSet.has(id));
327
+ return newIds.length > 0 ? [...current, ...newIds] : current;
328
+ });
329
+ }, [sources]);
330
+
331
+ return (
332
+ <div className={cn("flex flex-col gap-6 font-sans", className)}>
333
+ {/* Heading */}
334
+ <h2 className="text-h1 text-foreground">{applicantName}&apos;s Income</h2>
335
+
336
+ {/* Open Banking summary — left card + right chart */}
337
+ {totalIncome !== undefined && (
338
+ <div className="flex items-center gap-4">
339
+ {/* Left: bordered card — amount + button */}
340
+ <Card className="shrink-0 w-[202px]">
341
+ <CardContent className="flex flex-col gap-3 p-4">
342
+ <div className="flex flex-col gap-1 flex-1">
343
+ <span className="text-h2 text-foreground">
344
+ {formatCurrency(totalIncome)}
345
+ </span>
346
+ <span className="text-body-small text-muted-foreground">
347
+ Total latest 12 months
348
+ </span>
349
+ </div>
350
+ <Button
351
+ variant="secondary"
352
+ size="sm"
353
+ className="w-fit"
354
+ onClick={onConnectMore}
355
+ >
356
+ Add More Account +
357
+ </Button>
358
+ </CardContent>
359
+ </Card>
360
+
361
+ {/* Right: bare bar chart with Y-axis + X-axis */}
362
+ {incomeData && (
363
+ <IncomeBarChart
364
+ incomeData={incomeData}
365
+ bare
366
+ showLegend={false}
367
+ showYAxis
368
+ showXAxis
369
+ defaultPeriod={12}
370
+ height={160}
371
+ className="flex-1"
372
+ />
373
+ )}
374
+ </div>
375
+ )}
376
+
377
+ {/* Income Sources */}
378
+ <div className="flex flex-col gap-2">
379
+ <h3 className="text-h3 text-foreground">Income Sources</h3>
380
+ <div className="flex flex-col gap-1.5">
381
+ <span className="text-label-small text-muted-foreground">
382
+ Total Income
383
+ </span>
384
+ {/* Full-width indicator bar — green when totalIncome > 0, muted otherwise */}
385
+ <div
386
+ className={cn(
387
+ "h-5 w-full",
388
+ totalIncome ? "bg-primary" : "bg-muted",
389
+ )}
390
+ />
391
+ </div>
392
+ </div>
393
+
394
+ {/* Work Details */}
395
+ <div className="flex flex-col gap-3">
396
+ <h3 className="text-h3 text-foreground">Work Details</h3>
397
+ <Accordion
398
+ type="multiple"
399
+ value={openItems}
400
+ onValueChange={setOpenItems}
401
+ className="border-t border-border"
402
+ >
403
+ {sources.map((source) => (
404
+ <AccordionItem key={source.id} value={source.id}>
405
+ <AccordionTrigger>
406
+ {source.label ?? "Main Income Source"}
407
+ </AccordionTrigger>
408
+ <AccordionContent className="text-foreground">
409
+ <IncomeSourceForm
410
+ source={source}
411
+ onChange={(updates) => onSourceChange?.(source.id, updates)}
412
+ />
413
+ </AccordionContent>
414
+ </AccordionItem>
415
+ ))}
416
+ </Accordion>
417
+
418
+ <Button
419
+ variant="outline"
420
+ size="sm"
421
+ className="w-fit"
422
+ onClick={onAddSource}
423
+ >
424
+ Add More +
425
+ </Button>
426
+ </div>
427
+ </div>
428
+ );
429
+ }
@@ -0,0 +1,111 @@
1
+ import React from "react";
2
+ import {
3
+ TrendingUp,
4
+ Home,
5
+ ShoppingBag,
6
+ CreditCard,
7
+ PiggyBank,
8
+ TrendingDown,
9
+ } from "lucide-react";
10
+ import { Card, CardContent, CardHeader, CardTitle } from "./card";
11
+ import { cn } from "@/lib/utils";
12
+ import { formatCurrency } from "@/lib/format-currency";
13
+
14
+ // ─── Types ───────────────────────────────────────────────────────────────────
15
+
16
+ export type IncomingOutgoingsLabel =
17
+ | "Total Income"
18
+ | "Living Expenses"
19
+ | "Lifestyle Expenses"
20
+ | "Debt Repayments"
21
+ | "Surplus Income & Savings"
22
+ | "Over Spending";
23
+
24
+ export interface IncomingOutgoingsItem {
25
+ label: IncomingOutgoingsLabel;
26
+ /** Dollar value */
27
+ value: number;
28
+ /** CSS color string for the bar fill and icon */
29
+ color: string;
30
+ /** CSS color string for the bar track background */
31
+ bgColor: string;
32
+ /** Bar fill width as a percentage 0–100 */
33
+ pct: number;
34
+ }
35
+
36
+ export interface IncomingOutgoingsCardProps {
37
+ items: IncomingOutgoingsItem[];
38
+ title?: string;
39
+ className?: string;
40
+ }
41
+
42
+ // ─── Icon map ─────────────────────────────────────────────────────────────────
43
+
44
+ const ICON_MAP: Record<
45
+ IncomingOutgoingsLabel,
46
+ React.ComponentType<{ size?: number; className?: string }>
47
+ > = {
48
+ "Total Income": TrendingUp,
49
+ "Living Expenses": Home,
50
+ "Lifestyle Expenses": ShoppingBag,
51
+ "Debt Repayments": CreditCard,
52
+ "Surplus Income & Savings": PiggyBank,
53
+ "Over Spending": TrendingDown,
54
+ };
55
+
56
+ // ─── Component ────────────────────────────────────────────────────────────────
57
+
58
+ export function IncomingOutgoingsCard({
59
+ items,
60
+ title = "Incoming and outgoings",
61
+ className,
62
+ }: IncomingOutgoingsCardProps) {
63
+ if (!items?.length) return null;
64
+
65
+ return (
66
+ <Card className={cn("h-full", className)}>
67
+ <CardHeader className="pb-2">
68
+ <CardTitle className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
69
+ {title}
70
+ </CardTitle>
71
+ </CardHeader>
72
+ <CardContent className="flex flex-col gap-5">
73
+ {items.map((item) => {
74
+ const Icon = ICON_MAP[item.label];
75
+ return (
76
+ <div key={item.label} className="flex flex-col gap-1">
77
+ <div className="flex items-center justify-between gap-2">
78
+ <span className="flex items-center gap-1.5 text-sm text-foreground">
79
+ {Icon && (
80
+ <Icon
81
+ size={16}
82
+ className="shrink-0"
83
+ style={{ color: item.color }}
84
+ />
85
+ )}
86
+ {item.label}
87
+ </span>
88
+ <span className="shrink-0 text-sm font-medium text-foreground">
89
+ {formatCurrency(item.value)}
90
+ </span>
91
+ </div>
92
+ <div
93
+ className="h-1.5 w-full overflow-hidden"
94
+ style={{ background: item.bgColor }}
95
+ aria-hidden="true"
96
+ >
97
+ <div
98
+ className="h-full transition-all"
99
+ style={{
100
+ background: item.color,
101
+ width: `${Math.min(100, Math.max(0, item.pct))}%`,
102
+ }}
103
+ />
104
+ </div>
105
+ </div>
106
+ );
107
+ })}
108
+ </CardContent>
109
+ </Card>
110
+ );
111
+ }