@wealthx/shadcn 1.4.1 → 1.5.1

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 +356 -176
  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 +367 -3
  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,180 @@
1
+ import React from "react";
2
+ import { Stepper, Step, StepItem } from "./stepper";
3
+
4
+ const DEFAULT_VIDEO_SRC =
5
+ "https://d1rndq5v7rs3ry.cloudfront.net/padua-landing-video.mp4";
6
+
7
+ // ---------------------------------------------------------------------------
8
+ // SignupVideoPanel
9
+ // ---------------------------------------------------------------------------
10
+
11
+ export interface SignupVideoPanelProps {
12
+ /** Defaults to WealthX CDN landing video. */
13
+ videoSrc?: string;
14
+ }
15
+
16
+ export function SignupVideoPanel({
17
+ videoSrc = DEFAULT_VIDEO_SRC,
18
+ }: SignupVideoPanelProps) {
19
+ return (
20
+ <div className="hidden @md:block relative bg-neutral-900 overflow-hidden">
21
+ <video
22
+ autoPlay
23
+ muted
24
+ loop
25
+ playsInline
26
+ className="absolute inset-0 w-full h-full object-cover"
27
+ >
28
+ <source src={videoSrc} type="video/mp4" />
29
+ </video>
30
+ </div>
31
+ );
32
+ }
33
+
34
+ // ---------------------------------------------------------------------------
35
+ // SignupShell — backoffice signup wizard layout
36
+ // ---------------------------------------------------------------------------
37
+
38
+ export interface SignupShellProps {
39
+ /** Ordered list of step labels used by the stepper and h2 heading. */
40
+ steps: string[];
41
+ /** 0-based active step index. When >= steps.length the success layout is shown. */
42
+ step: number;
43
+ children: React.ReactNode;
44
+ /** Sticky footer content (Prev/Next buttons). Hidden in success state. */
45
+ footer?: React.ReactNode;
46
+ videoSrc?: string;
47
+ /** Page heading above the stepper. Defaults to "Sign Up". */
48
+ title?: string;
49
+ }
50
+
51
+ export function SignupShell({
52
+ steps,
53
+ step,
54
+ children,
55
+ footer,
56
+ videoSrc,
57
+ title = "Sign Up",
58
+ }: SignupShellProps) {
59
+ const isSuccess = step >= steps.length;
60
+
61
+ return (
62
+ <div className="@md:grid @md:grid-cols-2 h-screen overflow-hidden">
63
+ <SignupVideoPanel videoSrc={videoSrc} />
64
+ <div className="flex flex-col h-full overflow-hidden">
65
+ {isSuccess ? (
66
+ <div className="flex-1 overflow-y-auto min-h-0 flex items-center justify-center">
67
+ {children}
68
+ </div>
69
+ ) : (
70
+ <>
71
+ <div className="flex-1 overflow-y-auto min-h-0">
72
+ <div className="flex min-h-full justify-center px-4 py-6 @sm:px-10 @sm:py-10">
73
+ <div className="w-full max-w-[560px] flex flex-col gap-8">
74
+ <h1 className="text-3xl font-bold text-foreground text-center">
75
+ {title}
76
+ </h1>
77
+ <Stepper activeStep={step} className="w-full">
78
+ {steps.map((label) => (
79
+ <Step key={label}>
80
+ <StepItem label={label} />
81
+ </Step>
82
+ ))}
83
+ </Stepper>
84
+ <h2 className="text-2xl font-bold text-foreground">
85
+ {steps[step]}
86
+ </h2>
87
+ {children}
88
+ </div>
89
+ </div>
90
+ </div>
91
+ {footer && (
92
+ <div className="shrink-0 border-t border-border bg-background">
93
+ <div className="w-full max-w-[560px] mx-auto px-0 py-4 flex justify-between">
94
+ {footer}
95
+ </div>
96
+ </div>
97
+ )}
98
+ </>
99
+ )}
100
+ </div>
101
+ </div>
102
+ );
103
+ }
104
+
105
+ // ---------------------------------------------------------------------------
106
+ // FrontendShell — client-facing signup wizard layout
107
+ // ---------------------------------------------------------------------------
108
+
109
+ export interface FrontendShellProps {
110
+ /** Step labels for the stepper. Required when stepIndex is provided. */
111
+ steps?: string[];
112
+ /** 0-based active step. When undefined the stepper is hidden. */
113
+ stepIndex?: number;
114
+ children: React.ReactNode;
115
+ footer?: React.ReactNode;
116
+ /** When true renders a centered layout without stepper/title (success screen). */
117
+ isSuccess?: boolean;
118
+ videoSrc?: string;
119
+ /** Page heading. Defaults to "Create Account". */
120
+ title?: string;
121
+ }
122
+
123
+ export function FrontendShell({
124
+ steps,
125
+ stepIndex,
126
+ children,
127
+ footer,
128
+ isSuccess = false,
129
+ videoSrc,
130
+ title = "Create Account",
131
+ }: FrontendShellProps) {
132
+ const hasStepper = stepIndex !== undefined && steps !== undefined;
133
+
134
+ return (
135
+ <div className="@md:grid @md:grid-cols-2 h-screen overflow-hidden">
136
+ <SignupVideoPanel videoSrc={videoSrc} />
137
+ <div className="flex flex-col h-full overflow-hidden">
138
+ {isSuccess ? (
139
+ <div className="flex-1 overflow-y-auto min-h-0 flex items-center justify-center">
140
+ {children}
141
+ </div>
142
+ ) : (
143
+ <>
144
+ <div className="flex-1 overflow-y-auto min-h-0">
145
+ <div className="flex min-h-full justify-center px-4 py-6 @sm:px-10 @sm:py-10">
146
+ <div className="w-full max-w-[520px] flex flex-col gap-8">
147
+ <h1 className="text-3xl font-bold text-foreground text-center">
148
+ {title}
149
+ </h1>
150
+ {hasStepper && (
151
+ <Stepper activeStep={stepIndex} className="w-full">
152
+ {steps!.map((label) => (
153
+ <Step key={label}>
154
+ <StepItem label={label} />
155
+ </Step>
156
+ ))}
157
+ </Stepper>
158
+ )}
159
+ {hasStepper && (
160
+ <h2 className="text-2xl font-bold text-foreground">
161
+ {steps![stepIndex!]}
162
+ </h2>
163
+ )}
164
+ {children}
165
+ </div>
166
+ </div>
167
+ </div>
168
+ {footer && (
169
+ <div className="shrink-0 border-t border-border bg-background">
170
+ <div className="w-full max-w-[520px] mx-auto px-0 py-4 flex justify-between">
171
+ {footer}
172
+ </div>
173
+ </div>
174
+ )}
175
+ </>
176
+ )}
177
+ </div>
178
+ </div>
179
+ );
180
+ }
@@ -32,6 +32,8 @@ export interface StageTimelineTask {
32
32
  title: string;
33
33
  completed: boolean;
34
34
  aiAgentName?: string | null;
35
+ /** When provided alongside `aiAgentName`, shows the auto-complete toggle switch. */
36
+ autoCompleteEnabled?: boolean;
35
37
  }
36
38
 
37
39
  export interface StageTimelineStage {
@@ -48,6 +50,8 @@ export interface StageTimelineProps {
48
50
  stages: StageTimelineStage[];
49
51
  /** Called when a task checkbox is toggled. */
50
52
  onTaskToggle?: (stageId: string, taskId: string) => void;
53
+ /** Called when the auto-complete switch on a task is toggled. */
54
+ onTaskAutoCompleteToggle?: (stageId: string, taskId: string) => void;
51
55
  /** Shows a loading skeleton instead of stages. */
52
56
  isLoading?: boolean;
53
57
  className?: string;
@@ -60,6 +64,7 @@ export interface StageTimelineProps {
60
64
  export function StageTimeline({
61
65
  stages,
62
66
  onTaskToggle,
67
+ onTaskAutoCompleteToggle,
63
68
  isLoading = false,
64
69
  className,
65
70
  }: StageTimelineProps) {
@@ -186,12 +191,18 @@ export function StageTimeline({
186
191
  title={task.title}
187
192
  completed={task.completed}
188
193
  aiAgentName={task.aiAgentName}
194
+ autoCompleteEnabled={task.autoCompleteEnabled}
189
195
  size="sm"
190
196
  onToggle={
191
197
  onTaskToggle
192
198
  ? () => onTaskToggle(stage.id, task.id)
193
199
  : undefined
194
200
  }
201
+ onAutoCompleteToggle={
202
+ onTaskAutoCompleteToggle
203
+ ? () => onTaskAutoCompleteToggle(stage.id, task.id)
204
+ : undefined
205
+ }
195
206
  />
196
207
  ))}
197
208
  </AccordionContent>
@@ -0,0 +1,68 @@
1
+ import React from "react";
2
+ import { cn } from "@/lib/utils";
3
+ import { Button } from "@/components/ui/button";
4
+
5
+ /**
6
+ * Full-screen success card shown after a loan application is submitted.
7
+ * Extracted from the submitted/ page in the loan application flow.
8
+ */
9
+
10
+ export type SubmissionConfirmationCardProps = {
11
+ onViewSubmission?: () => void;
12
+ className?: string;
13
+ };
14
+
15
+ function CircleCheckIcon({ className }: { className?: string }) {
16
+ return (
17
+ <svg
18
+ xmlns="http://www.w3.org/2000/svg"
19
+ viewBox="0 0 80 80"
20
+ fill="none"
21
+ className={cn("size-20", className)}
22
+ aria-hidden="true"
23
+ >
24
+ <circle cx="40" cy="40" r="38" stroke="currentColor" strokeWidth="3" />
25
+ <path
26
+ d="M24 40l12 12 20-24"
27
+ stroke="currentColor"
28
+ strokeWidth="3.5"
29
+ strokeLinecap="round"
30
+ strokeLinejoin="round"
31
+ />
32
+ </svg>
33
+ );
34
+ }
35
+
36
+ export function SubmissionConfirmationCard({
37
+ onViewSubmission,
38
+ className,
39
+ }: SubmissionConfirmationCardProps) {
40
+ return (
41
+ <div
42
+ className={cn(
43
+ "flex flex-col items-center gap-6 px-6 py-12 text-center",
44
+ className,
45
+ )}
46
+ >
47
+ <CircleCheckIcon className="text-primary" />
48
+
49
+ <div className="flex flex-col gap-2">
50
+ <p className="text-2xl font-bold">Awesome!</p>
51
+ <p className="text-2xl font-bold">
52
+ You&apos;ve submitted your loan application!
53
+ </p>
54
+ </div>
55
+
56
+ <p className="max-w-sm text-sm text-muted-foreground">
57
+ Your broker will take a look at your loan application and get back to
58
+ you with the results soon!
59
+ </p>
60
+
61
+ {onViewSubmission && (
62
+ <Button type="button" variant="outline" onClick={onViewSubmission}>
63
+ View Your Submission
64
+ </Button>
65
+ )}
66
+ </div>
67
+ );
68
+ }
@@ -0,0 +1,207 @@
1
+ import React from "react";
2
+ import { ChevronRight } from "lucide-react";
3
+ import { cn } from "@/lib/utils";
4
+ import { formatCurrency } from "@/lib/format-currency";
5
+ import { Button } from "./button";
6
+ import { Skeleton } from "./skeleton";
7
+
8
+ /**
9
+ * Organism — "Top 3 Loans Available" section for the Borrowing Capacity page.
10
+ *
11
+ * Layout:
12
+ * - Heading row: "Top 3 Loans Available" (left) + "See All Options" link (right)
13
+ * - Two-column body:
14
+ * - Left: up to 3 `TopThreeProductItem` rows (lender logo, rate, max loan, repayment)
15
+ * - Right: Outcome panel (descriptive text + CTA buttons)
16
+ *
17
+ * All values are pre-formatted / typed — business logic stays in the app layer.
18
+ */
19
+
20
+ // ─── Sub-types ───────────────────────────────────────────────────────────────
21
+
22
+ export interface TopThreeProductItem {
23
+ /** Lender display name (e.g. "ANZ") */
24
+ lender: string;
25
+ /** URL for the lender logo image. Falls back to initials if omitted. */
26
+ lenderLogoUrl?: string;
27
+ /** Interest rate as a percentage (e.g. 5.5 → displayed as "5.50%") */
28
+ interestRate: number;
29
+ /** true = Variable rate, false = Fixed rate */
30
+ isVariable: boolean;
31
+ /** Maximum loan amount in AUD dollars */
32
+ maxLoanAmount: number;
33
+ /** Monthly repayment in AUD dollars */
34
+ monthlyRepayment: number;
35
+ }
36
+
37
+ export interface TopThreeProductProps {
38
+ /** Up to 3 loan products to display */
39
+ items?: TopThreeProductItem[];
40
+ /** Outcome summary text shown in the right panel */
41
+ outcomeText?: string;
42
+ /** Called when "See All Options" is clicked */
43
+ onSeeAllOptions?: () => void;
44
+ /** Called when "Talk To Your Broker" CTA is clicked */
45
+ onTalkToBroker?: () => void;
46
+ /** Called when "Start Loan Application" CTA is clicked */
47
+ onStartLoanApplication?: () => void;
48
+ /** Replace content with a skeleton loading state */
49
+ isLoading?: boolean;
50
+ className?: string;
51
+ }
52
+
53
+ // ─── Internal stat cell ──────────────────────────────────────────────────────
54
+
55
+ function StatCell({ value, label }: { value: React.ReactNode; label: string }) {
56
+ return (
57
+ <div className="flex flex-col items-center gap-0.5 text-center">
58
+ <span className="text-base font-semibold tabular-nums text-foreground">
59
+ {value}
60
+ </span>
61
+ <span className="text-xs text-muted-foreground">{label}</span>
62
+ </div>
63
+ );
64
+ }
65
+
66
+ // ─── Internal product row ─────────────────────────────────────────────────────
67
+
68
+ function ProductRow({ item }: { item: TopThreeProductItem }) {
69
+ const initials = item.lender
70
+ .split(" ")
71
+ .map((w) => w[0])
72
+ .slice(0, 2)
73
+ .join("");
74
+
75
+ return (
76
+ <div className="flex items-center gap-4 py-3">
77
+ {/* Lender logo / initials fallback */}
78
+ <div className="flex h-10 w-10 shrink-0 items-center justify-center border border-border bg-muted text-xs font-semibold text-muted-foreground">
79
+ {item.lenderLogoUrl ? (
80
+ <img
81
+ src={item.lenderLogoUrl}
82
+ alt={item.lender}
83
+ className="h-full w-full object-contain"
84
+ />
85
+ ) : (
86
+ initials
87
+ )}
88
+ </div>
89
+
90
+ {/* Stats — rate, max loan, repayment */}
91
+ <div className="flex flex-1 items-center justify-between gap-2">
92
+ <StatCell
93
+ value={`${item.interestRate.toFixed(2)}%`}
94
+ label={item.isVariable ? "Variable" : "Fixed"}
95
+ />
96
+ <StatCell
97
+ value={formatCurrency(item.maxLoanAmount)}
98
+ label="Max Loan Amount"
99
+ />
100
+ <StatCell
101
+ value={formatCurrency(item.monthlyRepayment)}
102
+ label="Monthly Repayments"
103
+ />
104
+ </div>
105
+ </div>
106
+ );
107
+ }
108
+
109
+ // ─── Main component ───────────────────────────────────────────────────────────
110
+
111
+ export function TopThreeProduct({
112
+ items = [],
113
+ outcomeText,
114
+ onSeeAllOptions,
115
+ onTalkToBroker,
116
+ onStartLoanApplication,
117
+ isLoading = false,
118
+ className,
119
+ }: TopThreeProductProps) {
120
+ const showOutcome = Boolean(
121
+ outcomeText || onTalkToBroker || onStartLoanApplication,
122
+ );
123
+
124
+ return (
125
+ <div className={cn("flex flex-col gap-3", className)}>
126
+ {/* Heading row */}
127
+ <div className="flex items-center justify-between">
128
+ <span className="text-sm font-semibold text-foreground">
129
+ Top 3 Loans Available
130
+ </span>
131
+ {onSeeAllOptions && (
132
+ <button
133
+ type="button"
134
+ onClick={onSeeAllOptions}
135
+ className="flex items-center gap-1 text-sm text-primary transition-opacity hover:opacity-70"
136
+ >
137
+ See All Options
138
+ <ChevronRight size={14} className="shrink-0" />
139
+ </button>
140
+ )}
141
+ </div>
142
+
143
+ {/* Body — products + outcome */}
144
+ <div className="flex gap-4">
145
+ {/* Product list */}
146
+ <div className="flex flex-1 flex-col divide-y divide-border">
147
+ {isLoading
148
+ ? Array.from({ length: 3 }).map((_, i) => (
149
+ <div key={i} className="flex items-center gap-4 py-3">
150
+ <Skeleton className="h-10 w-10 shrink-0" />
151
+ <div className="flex flex-1 justify-between gap-4">
152
+ <Skeleton className="h-8 w-16" />
153
+ <Skeleton className="h-8 w-20" />
154
+ <Skeleton className="h-8 w-20" />
155
+ </div>
156
+ </div>
157
+ ))
158
+ : items.length > 0
159
+ ? items
160
+ .slice(0, 3)
161
+ .map((item, i) => (
162
+ <ProductRow key={`${item.lender}-${i}`} item={item} />
163
+ ))
164
+ : !isLoading && (
165
+ <p className="py-6 text-center text-sm text-muted-foreground">
166
+ No lender options available for this scenario.
167
+ </p>
168
+ )}
169
+ </div>
170
+
171
+ {/* Outcome panel */}
172
+ {showOutcome && (
173
+ <div className="flex w-48 shrink-0 flex-col gap-3 border-l border-border pl-4">
174
+ <span className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">
175
+ Outcome
176
+ </span>
177
+ {outcomeText && (
178
+ <p className="text-sm text-foreground">{outcomeText}</p>
179
+ )}
180
+ <div className="flex flex-col gap-2">
181
+ {onTalkToBroker && (
182
+ <Button
183
+ variant="default"
184
+ size="sm"
185
+ onClick={onTalkToBroker}
186
+ className="w-full"
187
+ >
188
+ Talk To Your Broker
189
+ </Button>
190
+ )}
191
+ {onStartLoanApplication && (
192
+ <Button
193
+ variant="outline"
194
+ size="sm"
195
+ onClick={onStartLoanApplication}
196
+ className="w-full"
197
+ >
198
+ Start Loan Application
199
+ </Button>
200
+ )}
201
+ </div>
202
+ </div>
203
+ )}
204
+ </div>
205
+ </div>
206
+ );
207
+ }
@@ -0,0 +1,59 @@
1
+ import React from "react";
2
+ import { cn } from "@/lib/utils";
3
+
4
+ /**
5
+ * Section header block used above each chart on the Money (Transactions) page.
6
+ *
7
+ * Matches the app design: large value at the top, category label below,
8
+ * optional period text and footnote beneath.
9
+ *
10
+ * Layout:
11
+ * ┌─────────────────────────────────────────┐
12
+ * │ $37,085 [optional action] │
13
+ * │ Cash Balance │
14
+ * │ 30 Days Total │
15
+ * │ (Based on connected bank transactions) │
16
+ * └─────────────────────────────────────────┘
17
+ */
18
+
19
+ export interface TransactionsSummaryBlockProps {
20
+ /** Pre-formatted total value — e.g. "$37,085" — displayed prominently at top */
21
+ value: string;
22
+ /** Section label — e.g. "Cash Balance", "Income", "Expense" */
23
+ label: string;
24
+ /** Period text — e.g. "30 Days Total" */
25
+ period?: string;
26
+ /** Small footnote — e.g. "(Based on connected bank transactions)" */
27
+ footnote?: string;
28
+ /** Optional trailing element — e.g. a Button for "Set Goal" */
29
+ action?: React.ReactNode;
30
+ className?: string;
31
+ }
32
+
33
+ export function TransactionsSummaryBlock({
34
+ value,
35
+ label,
36
+ period,
37
+ footnote,
38
+ action,
39
+ className,
40
+ }: TransactionsSummaryBlockProps) {
41
+ return (
42
+ <div
43
+ className={cn("flex items-start justify-between gap-2 py-3", className)}
44
+ >
45
+ <div className="flex flex-col gap-0.5">
46
+ <p className="text-2xl font-bold tabular-nums text-foreground">
47
+ {value}
48
+ </p>
49
+ <p className="text-sm font-medium text-foreground">{label}</p>
50
+ {period && <p className="text-xs text-muted-foreground">{period}</p>}
51
+ {footnote && (
52
+ <p className="text-xs text-muted-foreground">{footnote}</p>
53
+ )}
54
+ </div>
55
+
56
+ {action && <div className="shrink-0">{action}</div>}
57
+ </div>
58
+ );
59
+ }
package/src/lib/colors.ts CHANGED
@@ -45,6 +45,18 @@ export function getContrastText(backgroundColor: string): string {
45
45
  return luminance > 0.179 ? CONTRAST_DARK : CONTRAST_LIGHT;
46
46
  }
47
47
 
48
+ /**
49
+ * Returns a CSS color-mix() string blending `color` with transparent at the given fill opacity.
50
+ * Used for swatch/chip backgrounds in income/expense/debt indicators.
51
+ *
52
+ * @example colorMixSwatch("#3B82F6") // "color-mix(in srgb, #3B82F6 15%, transparent)"
53
+ * @example colorMixSwatch("#3B82F6", 0.3) // "color-mix(in srgb, #3B82F6 30%, transparent)"
54
+ */
55
+ export function colorMixSwatch(color: string, fillOpacity = 0.15): string {
56
+ const percent = Math.round(fillOpacity * 100);
57
+ return `color-mix(in srgb, ${color} ${percent}%, transparent)`;
58
+ }
59
+
48
60
  /** Convert hex to oklch() CSS string */
49
61
  export function hexToOklch(hex: string): string {
50
62
  const [r, g, b] = hexToRgb(hex);
@@ -54,11 +54,11 @@ export function formatDateWithWeekday(iso: string): string {
54
54
  * Returns raw string on parse failure.
55
55
  */
56
56
  export function formatDateLong(date: Date | string): string {
57
+ const d = typeof date === "string" ? safeParse(date) : date;
57
58
  try {
58
- const d = typeof date === "string" ? safeParse(date) : date;
59
59
  return format(d, "EEEE, d MMMM");
60
60
  } catch {
61
- return String(date);
61
+ return d.toLocaleDateString();
62
62
  }
63
63
  }
64
64