@wealthx/shadcn 1.3.2 → 1.3.4

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 (313) hide show
  1. package/.turbo/turbo-build.log +227 -191
  2. package/CHANGELOG.md +12 -0
  3. package/dist/{chunk-2UM72RJ7.mjs → chunk-2D3HQPFN.mjs} +12 -10
  4. package/dist/chunk-2EM2FRU6.mjs +613 -0
  5. package/dist/{chunk-FH6QVUVZ.mjs → chunk-2GIYVERS.mjs} +2 -2
  6. package/dist/chunk-2P7HP7LR.mjs +68 -0
  7. package/dist/{chunk-HISNT2MG.mjs → chunk-37AE3OM5.mjs} +5 -5
  8. package/dist/{chunk-HBZLGDIN.mjs → chunk-3ERBUVHC.mjs} +169 -110
  9. package/dist/{chunk-C7CQJNMR.mjs → chunk-3VDET466.mjs} +2 -2
  10. package/dist/{chunk-462HMNO4.mjs → chunk-4MM7LHM5.mjs} +2 -2
  11. package/dist/{chunk-QMY3AZJH.mjs → chunk-4Z66LMIQ.mjs} +2 -2
  12. package/dist/{chunk-U5X52X37.mjs → chunk-57ZXILTS.mjs} +6 -6
  13. package/dist/{chunk-2A5RRQGG.mjs → chunk-5NF6T2RS.mjs} +11 -20
  14. package/dist/{chunk-3OYFOX3X.mjs → chunk-5VOTTIXF.mjs} +2 -2
  15. package/dist/{chunk-LBMRIB3G.mjs → chunk-6AJUS7VX.mjs} +1 -1
  16. package/dist/{chunk-OODBHKG7.mjs → chunk-6HIOM2HL.mjs} +7 -4
  17. package/dist/{chunk-BDYZCBRT.mjs → chunk-6QAFGZC2.mjs} +2 -2
  18. package/dist/{chunk-U4NDAF2P.mjs → chunk-6TX73WG7.mjs} +1 -1
  19. package/dist/{chunk-GD4BJDJR.mjs → chunk-7BTFGCFC.mjs} +4 -4
  20. package/dist/{chunk-FAKPBKLT.mjs → chunk-7GWRPXHD.mjs} +4 -4
  21. package/dist/{chunk-NMOI6CQD.mjs → chunk-7YI3HEBH.mjs} +5 -5
  22. package/dist/{chunk-T4BJLT57.mjs → chunk-AE7MASLF.mjs} +5 -5
  23. package/dist/{chunk-VLQZANBF.mjs → chunk-AFML43VJ.mjs} +6 -1
  24. package/dist/chunk-BBXSNDS3.mjs +260 -0
  25. package/dist/chunk-BOW7U26Y.mjs +203 -0
  26. package/dist/{chunk-34NWQURD.mjs → chunk-BS75ICOO.mjs} +2 -2
  27. package/dist/chunk-D2NSIIXG.mjs +394 -0
  28. package/dist/{chunk-3GF7OVTP.mjs → chunk-DGNHGNYH.mjs} +2 -2
  29. package/dist/{chunk-VLARHE5V.mjs → chunk-DMXYRCHM.mjs} +6 -6
  30. package/dist/{chunk-OGOYQ7BG.mjs → chunk-DQB4EPIS.mjs} +1 -1
  31. package/dist/{chunk-MIZQHHUO.mjs → chunk-FL6DZFJK.mjs} +106 -38
  32. package/dist/{chunk-I3RZS7V2.mjs → chunk-FLL633WS.mjs} +19 -33
  33. package/dist/{chunk-PBL4OQV2.mjs → chunk-FTPBQVQ6.mjs} +4 -4
  34. package/dist/chunk-FYPSTTEJ.mjs +169 -0
  35. package/dist/{chunk-6O6KD7CE.mjs → chunk-G27TSQLQ.mjs} +6 -6
  36. package/dist/{chunk-66MI7Q4B.mjs → chunk-GT3RU6GA.mjs} +2 -2
  37. package/dist/{chunk-D6ID6M4V.mjs → chunk-GTAVSBDO.mjs} +2 -2
  38. package/dist/{chunk-24FUO7TD.mjs → chunk-H6NQTIF4.mjs} +2 -2
  39. package/dist/{chunk-7DHU4VGG.mjs → chunk-HK4HUQTV.mjs} +2 -2
  40. package/dist/chunk-I4KVSZCH.mjs +101 -0
  41. package/dist/{chunk-RGVKLTLH.mjs → chunk-IKXYTCSB.mjs} +2 -2
  42. package/dist/{chunk-Y6DWJSKZ.mjs → chunk-ISUA7DSB.mjs} +1 -1
  43. package/dist/{chunk-J5UICVJS.mjs → chunk-JPGL36WQ.mjs} +2 -2
  44. package/dist/{chunk-7XJHLGUV.mjs → chunk-JTK6VJXY.mjs} +2 -2
  45. package/dist/{chunk-7YAU5CY6.mjs → chunk-JVMXMFBB.mjs} +2 -2
  46. package/dist/{chunk-IAE3F7DR.mjs → chunk-JZY6TNIS.mjs} +21 -21
  47. package/dist/{chunk-K5A5L6T2.mjs → chunk-K4KOD3KR.mjs} +12 -12
  48. package/dist/{chunk-MBON7YRJ.mjs → chunk-K5QV4TT6.mjs} +3 -3
  49. package/dist/{chunk-IHMFS7NZ.mjs → chunk-K5VHK7CM.mjs} +21 -21
  50. package/dist/{chunk-RJI6GKVF.mjs → chunk-KCWNDYPZ.mjs} +5 -5
  51. package/dist/{chunk-UFYSFDER.mjs → chunk-KFH36NKF.mjs} +1 -1
  52. package/dist/{chunk-EBXQWIYG.mjs → chunk-KLTACJ2G.mjs} +5 -5
  53. package/dist/{chunk-3TTACBDP.mjs → chunk-KWD6GANL.mjs} +4 -4
  54. package/dist/{chunk-IOJRDS6V.mjs → chunk-L4NSRQ3T.mjs} +218 -147
  55. package/dist/{chunk-GYMYRIZP.mjs → chunk-LBTHZSBT.mjs} +2 -2
  56. package/dist/{chunk-AMQZRHEZ.mjs → chunk-LQULK2E3.mjs} +5 -5
  57. package/dist/{chunk-YJG55G2H.mjs → chunk-LR6LHDP3.mjs} +5 -5
  58. package/dist/{chunk-7PV3IWCN.mjs → chunk-M4VYX2PV.mjs} +19 -1
  59. package/dist/{chunk-P76HMUI6.mjs → chunk-MDUKXXIL.mjs} +2 -2
  60. package/dist/{chunk-LV35NGVG.mjs → chunk-N6Q5IPKT.mjs} +9 -9
  61. package/dist/{chunk-DOEO3CDL.mjs → chunk-NB3ZL36B.mjs} +1 -1
  62. package/dist/{chunk-XREGSKX3.mjs → chunk-NOOEKOWY.mjs} +5 -5
  63. package/dist/{chunk-NL3ZO62D.mjs → chunk-NT4FX27K.mjs} +1 -1
  64. package/dist/{chunk-QZ4RE6NA.mjs → chunk-NTYQWVLI.mjs} +6 -6
  65. package/dist/{chunk-ERGGHC2V.mjs → chunk-OEOOYMC2.mjs} +2 -2
  66. package/dist/{chunk-4GAWMKMI.mjs → chunk-OIKBW2QD.mjs} +291 -54
  67. package/dist/{chunk-DUJTAXMH.mjs → chunk-OKTJFDPN.mjs} +6 -6
  68. package/dist/chunk-OLKMCXAR.mjs +1219 -0
  69. package/dist/{chunk-EI5F6FMT.mjs → chunk-OWFQSXVD.mjs} +3 -3
  70. package/dist/{chunk-6DZEXFNB.mjs → chunk-P2N2PEFY.mjs} +3 -3
  71. package/dist/{chunk-NSLMILBT.mjs → chunk-P7CEBZM6.mjs} +2 -2
  72. package/dist/{chunk-7S5AESZO.mjs → chunk-PNRUH7JY.mjs} +6 -6
  73. package/dist/{chunk-ZU4NV6RG.mjs → chunk-PNSYFE3K.mjs} +2 -2
  74. package/dist/{chunk-JKGDCQTZ.mjs → chunk-QTRSCVQ3.mjs} +5 -5
  75. package/dist/{chunk-ABFDMHOR.mjs → chunk-QX7IFQSF.mjs} +5 -5
  76. package/dist/{chunk-CFMQP5QS.mjs → chunk-QXKGOMUX.mjs} +6 -6
  77. package/dist/{chunk-NQPOYKAQ.mjs → chunk-R2ON6CAN.mjs} +2 -2
  78. package/dist/{chunk-DBHJ5KC3.mjs → chunk-R4HCRDU5.mjs} +1 -1
  79. package/dist/{chunk-EWRB4PAD.mjs → chunk-RCAOCHWA.mjs} +14 -14
  80. package/dist/{chunk-EFRENWEJ.mjs → chunk-RSUIPKGX.mjs} +2 -2
  81. package/dist/{chunk-DGHAXJBN.mjs → chunk-S2FKV4M5.mjs} +5 -5
  82. package/dist/{chunk-RGU7HOEC.mjs → chunk-SET2ANTY.mjs} +5 -7
  83. package/dist/chunk-SFH2NJEJ.mjs +47 -0
  84. package/dist/{chunk-6AW4KJHE.mjs → chunk-SIVYAI3M.mjs} +12 -12
  85. package/dist/{chunk-5FQIKDKP.mjs → chunk-THVO2N47.mjs} +8 -8
  86. package/dist/{chunk-JMHR3YGZ.mjs → chunk-TLAWKTSA.mjs} +3 -3
  87. package/dist/{chunk-HVY6KCCF.mjs → chunk-TOWTPLRC.mjs} +68 -72
  88. package/dist/{chunk-6JQFUE5I.mjs → chunk-UALR6JGV.mjs} +2 -2
  89. package/dist/{chunk-N6TNTQL6.mjs → chunk-UJZ4UHWI.mjs} +9 -11
  90. package/dist/{chunk-MARPPFOJ.mjs → chunk-UNACI2YK.mjs} +2 -2
  91. package/dist/{chunk-3NCUZIFP.mjs → chunk-V6XGXYCJ.mjs} +7 -7
  92. package/dist/chunk-VB5M6OZQ.mjs +57 -0
  93. package/dist/{chunk-5IS7G74I.mjs → chunk-VY5NEUP7.mjs} +6 -6
  94. package/dist/{chunk-JHJHG4GO.mjs → chunk-WE4YKBDE.mjs} +2 -2
  95. package/dist/{chunk-BKNFWEH2.mjs → chunk-WL6WVV47.mjs} +3 -3
  96. package/dist/{chunk-FWCSY2DS.mjs → chunk-WNQUEZJF.mjs} +22 -1
  97. package/dist/{chunk-2Y7YJKPE.mjs → chunk-WZ6UJCBL.mjs} +1 -1
  98. package/dist/{chunk-UMTOX62O.mjs → chunk-XYPW2XA5.mjs} +13 -10
  99. package/dist/chunk-Y2MTAVAK.mjs +34 -0
  100. package/dist/{chunk-6CR5N2JW.mjs → chunk-YCWLFG27.mjs} +6 -6
  101. package/dist/{chunk-PU4YZQXV.mjs → chunk-YE67AALL.mjs} +12 -12
  102. package/dist/{chunk-M3FV7LOK.mjs → chunk-YEWNFK5S.mjs} +6 -1
  103. package/dist/{chunk-R3VSPKNP.mjs → chunk-YIZHS72Z.mjs} +11 -12
  104. package/dist/{chunk-7PYJD5JI.mjs → chunk-ZEDMKQK2.mjs} +2 -2
  105. package/dist/{chunk-N2PT566P.mjs → chunk-ZFCDYW6N.mjs} +4 -4
  106. package/dist/chunk-ZGQIVGIN.mjs +57 -0
  107. package/dist/{chunk-Q2BGOAMG.mjs → chunk-ZKWXDQDG.mjs} +4 -4
  108. package/dist/{chunk-GHC7LLUX.mjs → chunk-ZOWL2L5J.mjs} +5 -5
  109. package/dist/components/ui/accordion.mjs +3 -3
  110. package/dist/components/ui/add-column-modal.js +2 -2
  111. package/dist/components/ui/add-column-modal.mjs +10 -10
  112. package/dist/components/ui/add-lead-modal.js +424 -82
  113. package/dist/components/ui/add-lead-modal.mjs +12 -9
  114. package/dist/components/ui/advisor-card.js +2 -2
  115. package/dist/components/ui/advisor-card.mjs +8 -8
  116. package/dist/components/ui/ai-assistant-drawer.js +2 -2
  117. package/dist/components/ui/ai-assistant-drawer.mjs +9 -9
  118. package/dist/components/ui/ai-builder.js +958 -0
  119. package/dist/components/ui/ai-builder.mjs +25 -0
  120. package/dist/components/ui/ai-conversations.js +2045 -0
  121. package/dist/components/ui/ai-conversations.mjs +41 -0
  122. package/dist/components/ui/alert-dialog.js +2 -2
  123. package/dist/components/ui/alert-dialog.mjs +5 -5
  124. package/dist/components/ui/alert.mjs +3 -3
  125. package/dist/components/ui/appointment-action-dialogs.js +19 -3
  126. package/dist/components/ui/appointment-action-dialogs.mjs +15 -14
  127. package/dist/components/ui/appointment-availability-settings.js +181 -111
  128. package/dist/components/ui/appointment-availability-settings.mjs +20 -18
  129. package/dist/components/ui/appointment-book-dialog.js +113 -24
  130. package/dist/components/ui/appointment-book-dialog.mjs +21 -20
  131. package/dist/components/ui/appointment-calendar-view.js +19 -3
  132. package/dist/components/ui/appointment-calendar-view.mjs +10 -9
  133. package/dist/components/ui/appointment-detail-sheet.js +19 -3
  134. package/dist/components/ui/appointment-detail-sheet.mjs +18 -17
  135. package/dist/components/ui/appointment-gmail-connect.js +49 -89
  136. package/dist/components/ui/appointment-gmail-connect.mjs +8 -9
  137. package/dist/components/ui/appointment-mini-card.js +2 -2
  138. package/dist/components/ui/appointment-mini-card.mjs +6 -6
  139. package/dist/components/ui/appointment-time-slot-picker.mjs +6 -6
  140. package/dist/components/ui/appointment-upcoming-card.js +19 -3
  141. package/dist/components/ui/appointment-upcoming-card.mjs +15 -14
  142. package/dist/components/ui/auth-logo.js +95 -0
  143. package/dist/components/ui/auth-logo.mjs +8 -0
  144. package/dist/components/ui/auth-page-layout.js +108 -0
  145. package/dist/components/ui/auth-page-layout.mjs +8 -0
  146. package/dist/components/ui/avatar.mjs +3 -3
  147. package/dist/components/ui/backoffice-alert-history-chart.js +2 -2
  148. package/dist/components/ui/backoffice-alert-history-chart.mjs +9 -9
  149. package/dist/components/ui/backoffice-alerts-chart.js +2 -2
  150. package/dist/components/ui/backoffice-alerts-chart.mjs +11 -11
  151. package/dist/components/ui/backoffice-connections-chart.js +2 -2
  152. package/dist/components/ui/backoffice-connections-chart.mjs +11 -11
  153. package/dist/components/ui/backoffice-contact-history-chart.js +2 -2
  154. package/dist/components/ui/backoffice-contact-history-chart.mjs +9 -9
  155. package/dist/components/ui/badge.mjs +4 -4
  156. package/dist/components/ui/borrowing-capacity-line-chart.js +145 -132
  157. package/dist/components/ui/borrowing-capacity-line-chart.mjs +9 -9
  158. package/dist/components/ui/button.js +2 -2
  159. package/dist/components/ui/button.mjs +4 -4
  160. package/dist/components/ui/calendar.js +17 -3
  161. package/dist/components/ui/calendar.mjs +6 -5
  162. package/dist/components/ui/card.mjs +3 -3
  163. package/dist/components/ui/cash-balance-line-chart.js +158 -158
  164. package/dist/components/ui/cash-balance-line-chart.mjs +9 -9
  165. package/dist/components/ui/cashflow-bar-chart.js +2 -2
  166. package/dist/components/ui/cashflow-bar-chart.mjs +9 -9
  167. package/dist/components/ui/chat-widget-primitives.js +573 -0
  168. package/dist/components/ui/chat-widget-primitives.mjs +21 -0
  169. package/dist/components/ui/chat-widget.js +1268 -0
  170. package/dist/components/ui/chat-widget.mjs +29 -0
  171. package/dist/components/ui/checkbox.mjs +3 -3
  172. package/dist/components/ui/chip.js +2 -2
  173. package/dist/components/ui/chip.mjs +6 -6
  174. package/dist/components/ui/color-picker.js +2 -2
  175. package/dist/components/ui/color-picker.mjs +7 -7
  176. package/dist/components/ui/combobox.mjs +3 -3
  177. package/dist/components/ui/data-table.js +2 -2
  178. package/dist/components/ui/data-table.mjs +12 -12
  179. package/dist/components/ui/date-picker.js +22 -6
  180. package/dist/components/ui/date-picker.mjs +9 -8
  181. package/dist/components/ui/dialog.js +2 -2
  182. package/dist/components/ui/dialog.mjs +5 -5
  183. package/dist/components/ui/document-checklist-template.js +630 -0
  184. package/dist/components/ui/document-checklist-template.mjs +15 -0
  185. package/dist/components/ui/drawer.js +2 -2
  186. package/dist/components/ui/drawer.mjs +3 -3
  187. package/dist/components/ui/dropdown-menu.mjs +3 -3
  188. package/dist/components/ui/empty.mjs +3 -3
  189. package/dist/components/ui/expense-bar-chart.js +2 -2
  190. package/dist/components/ui/expense-bar-chart.mjs +9 -9
  191. package/dist/components/ui/field.mjs +5 -5
  192. package/dist/components/ui/financial-cards.js +431 -291
  193. package/dist/components/ui/financial-cards.mjs +10 -9
  194. package/dist/components/ui/financial-drawers.js +4 -4
  195. package/dist/components/ui/financial-drawers.mjs +8 -8
  196. package/dist/components/ui/financial-primitives.mjs +3 -3
  197. package/dist/components/ui/financial-sections.js +8 -9
  198. package/dist/components/ui/financial-sections.mjs +12 -12
  199. package/dist/components/ui/form-primitives.mjs +8 -8
  200. package/dist/components/ui/income-bar-chart.js +2 -2
  201. package/dist/components/ui/income-bar-chart.mjs +9 -9
  202. package/dist/components/ui/input-group.js +2 -2
  203. package/dist/components/ui/input-group.mjs +7 -7
  204. package/dist/components/ui/input-otp.mjs +3 -3
  205. package/dist/components/ui/input.mjs +3 -3
  206. package/dist/components/ui/kanban-column.js +19 -23
  207. package/dist/components/ui/kanban-column.mjs +14 -14
  208. package/dist/components/ui/label.mjs +3 -3
  209. package/dist/components/ui/onboarding-layout.js +476 -0
  210. package/dist/components/ui/onboarding-layout.mjs +11 -0
  211. package/dist/components/ui/opportunity-card.js +2 -2
  212. package/dist/components/ui/opportunity-card.mjs +12 -12
  213. package/dist/components/ui/opportunity-edit-modals.js +22 -6
  214. package/dist/components/ui/opportunity-edit-modals.mjs +21 -20
  215. package/dist/components/ui/opportunity-summary-tab.js +991 -674
  216. package/dist/components/ui/opportunity-summary-tab.mjs +26 -26
  217. package/dist/components/ui/page-header.mjs +3 -3
  218. package/dist/components/ui/page-top-bar.mjs +3 -3
  219. package/dist/components/ui/pagination.js +2 -2
  220. package/dist/components/ui/pagination.mjs +6 -6
  221. package/dist/components/ui/password-strength-tooltip.js +197 -0
  222. package/dist/components/ui/password-strength-tooltip.mjs +11 -0
  223. package/dist/components/ui/pipeline-alerts.mjs +3 -3
  224. package/dist/components/ui/pipeline-board.js +19 -23
  225. package/dist/components/ui/pipeline-board.mjs +18 -18
  226. package/dist/components/ui/pipeline-chart.js +12 -6
  227. package/dist/components/ui/pipeline-chart.mjs +4 -3
  228. package/dist/components/ui/pipeline-dialogs.js +28 -12
  229. package/dist/components/ui/pipeline-dialogs.mjs +14 -13
  230. package/dist/components/ui/pipeline-primitives.mjs +6 -6
  231. package/dist/components/ui/popover.mjs +3 -3
  232. package/dist/components/ui/progress.mjs +3 -3
  233. package/dist/components/ui/property-cashflow-doughnut-chart.js +2 -2
  234. package/dist/components/ui/property-cashflow-doughnut-chart.mjs +9 -9
  235. package/dist/components/ui/property-debt-equity-doughnut-chart.js +2 -2
  236. package/dist/components/ui/property-debt-equity-doughnut-chart.mjs +9 -9
  237. package/dist/components/ui/property-mobile-estimate-line-chart.js +2 -2
  238. package/dist/components/ui/property-mobile-estimate-line-chart.mjs +9 -9
  239. package/dist/components/ui/radio-group.mjs +3 -3
  240. package/dist/components/ui/select.mjs +3 -3
  241. package/dist/components/ui/separator.mjs +3 -3
  242. package/dist/components/ui/sheet.mjs +3 -3
  243. package/dist/components/ui/sidebar-nav.js +6 -5
  244. package/dist/components/ui/sidebar-nav.mjs +7 -7
  245. package/dist/components/ui/skeleton.mjs +3 -3
  246. package/dist/components/ui/slider.mjs +3 -3
  247. package/dist/components/ui/sonner.mjs +2 -2
  248. package/dist/components/ui/spinner.mjs +3 -3
  249. package/dist/components/ui/stage-timeline.mjs +10 -10
  250. package/dist/components/ui/stepper.mjs +3 -3
  251. package/dist/components/ui/switch.mjs +3 -3
  252. package/dist/components/ui/table.mjs +3 -3
  253. package/dist/components/ui/tabs.mjs +3 -3
  254. package/dist/components/ui/textarea.mjs +3 -3
  255. package/dist/components/ui/toggle-group.mjs +4 -4
  256. package/dist/components/ui/toggle.mjs +3 -3
  257. package/dist/components/ui/tooltip.mjs +3 -3
  258. package/dist/components/ui/transactions-expense-categories-doughnut-chart.js +2 -2
  259. package/dist/components/ui/transactions-expense-categories-doughnut-chart.mjs +9 -9
  260. package/dist/components/ui/transactions-income-expense-bar-chart.js +2 -2
  261. package/dist/components/ui/transactions-income-expense-bar-chart.mjs +9 -9
  262. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.js +2 -2
  263. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.mjs +9 -9
  264. package/dist/components/ui/two-fa-setup-form.js +612 -0
  265. package/dist/components/ui/two-fa-setup-form.mjs +16 -0
  266. package/dist/components/ui/upload-card.js +187 -0
  267. package/dist/components/ui/upload-card.mjs +10 -0
  268. package/dist/components/ui/video-background.js +118 -0
  269. package/dist/components/ui/video-background.mjs +8 -0
  270. package/dist/index.js +12674 -9311
  271. package/dist/index.mjs +341 -245
  272. package/dist/lib/colors.mjs +1 -1
  273. package/dist/lib/theme-provider.mjs +1 -1
  274. package/dist/lib/typography.mjs +2 -2
  275. package/dist/lib/utils.js +8 -2
  276. package/dist/lib/utils.mjs +6 -4
  277. package/dist/styles.css +1 -1
  278. package/package.json +61 -1
  279. package/src/components/index.tsx +126 -1
  280. package/src/components/ui/add-lead-modal.tsx +101 -142
  281. package/src/components/ui/ai-builder.tsx +560 -0
  282. package/src/components/ui/ai-conversations.tsx +1690 -0
  283. package/src/components/ui/appointment-availability-settings.tsx +152 -101
  284. package/src/components/ui/appointment-book-dialog.tsx +138 -24
  285. package/src/components/ui/appointment-calendar-view.tsx +2 -3
  286. package/src/components/ui/appointment-gmail-connect.tsx +23 -42
  287. package/src/components/ui/auth-logo.tsx +50 -0
  288. package/src/components/ui/auth-page-layout.tsx +59 -0
  289. package/src/components/ui/borrowing-capacity-line-chart.tsx +10 -8
  290. package/src/components/ui/button.tsx +2 -2
  291. package/src/components/ui/calendar.tsx +2 -1
  292. package/src/components/ui/cash-balance-line-chart.tsx +11 -20
  293. package/src/components/ui/chart-shared.tsx +10 -0
  294. package/src/components/ui/chat-widget-primitives.tsx +336 -0
  295. package/src/components/ui/chat-widget.tsx +822 -0
  296. package/src/components/ui/document-checklist-template.tsx +264 -0
  297. package/src/components/ui/drawer.tsx +2 -2
  298. package/src/components/ui/financial-cards.tsx +176 -78
  299. package/src/components/ui/financial-drawers.tsx +2 -2
  300. package/src/components/ui/financial-sections.tsx +1 -1
  301. package/src/components/ui/kanban-column.tsx +2 -5
  302. package/src/components/ui/onboarding-layout.tsx +109 -0
  303. package/src/components/ui/opportunity-summary-tab.tsx +469 -142
  304. package/src/components/ui/password-strength-tooltip.tsx +70 -0
  305. package/src/components/ui/pipeline-chart.tsx +2 -6
  306. package/src/components/ui/sidebar-nav.tsx +1 -11
  307. package/src/components/ui/two-fa-setup-form.tsx +229 -0
  308. package/src/components/ui/upload-card.tsx +98 -0
  309. package/src/components/ui/video-background.tsx +55 -0
  310. package/src/lib/format-date.ts +26 -0
  311. package/src/lib/utils.ts +11 -0
  312. package/src/styles/styles-css.ts +1 -1
  313. package/tsup.config.ts +13 -0
@@ -0,0 +1,264 @@
1
+ import { useState } from "react";
2
+ import { GripVertical, Plus, Trash2 } from "lucide-react";
3
+ import { Button } from "./button";
4
+ import { Input } from "./input";
5
+ import { Switch } from "./switch";
6
+ import {
7
+ Select,
8
+ SelectContent,
9
+ SelectItem,
10
+ SelectTrigger,
11
+ SelectValue,
12
+ } from "./select";
13
+ import { cn } from "../../lib/utils";
14
+
15
+ /** Predefined document category options advisors can pick from. */
16
+ const DOCUMENT_TYPES = [
17
+ "Income Verification",
18
+ "Bank Statements",
19
+ "Rental Income",
20
+ "Property Evidence",
21
+ "Liabilities",
22
+ "Identity",
23
+ "Employment Contract",
24
+ "Notice of Assessment",
25
+ "Contract of Sale",
26
+ "Savings History",
27
+ ];
28
+
29
+ export interface ChecklistCategory {
30
+ id: string;
31
+ name: string;
32
+ /** Required for the main applicant. */
33
+ requiredMain: boolean;
34
+ /** Required for the co-applicant. */
35
+ requiredCo: boolean;
36
+ /** true when the advisor typed a custom name not in the predefined list. */
37
+ custom?: boolean;
38
+ }
39
+
40
+ export interface DocumentChecklistTemplateProps {
41
+ /** Initial list of checklist categories. */
42
+ categories?: ChecklistCategory[];
43
+ /** Called on every edit (add / change / delete). */
44
+ onChange?: (categories: ChecklistCategory[]) => void;
45
+ /** Called when the advisor clicks Save. */
46
+ onSave?: (categories: ChecklistCategory[]) => void;
47
+ /** Called when the advisor clicks Cancel. */
48
+ onCancel?: () => void;
49
+ className?: string;
50
+ }
51
+
52
+ /**
53
+ * DocumentChecklistTemplate — organism
54
+ *
55
+ * Editable list of document categories. Each category has separate Required
56
+ * toggles for Main and Co applicants. Name is chosen from a predefined
57
+ * dropdown or typed as a custom value.
58
+ */
59
+ export function DocumentChecklistTemplate({
60
+ categories: initial = [],
61
+ onChange,
62
+ onSave,
63
+ onCancel,
64
+ className,
65
+ }: DocumentChecklistTemplateProps) {
66
+ const [categories, setCategories] = useState<ChecklistCategory[]>(() =>
67
+ initial.map((c) => ({
68
+ ...c,
69
+ custom: c.custom ?? !DOCUMENT_TYPES.includes(c.name),
70
+ })),
71
+ );
72
+ const [isDirty, setIsDirty] = useState(false);
73
+
74
+ function update(next: ChecklistCategory[]) {
75
+ setCategories(next);
76
+ setIsDirty(true);
77
+ onChange?.(next);
78
+ }
79
+
80
+ function handleSelectType(id: string, value: string) {
81
+ if (value === "__custom__") {
82
+ update(
83
+ categories.map((c) =>
84
+ c.id === id ? { ...c, name: "", custom: true } : c,
85
+ ),
86
+ );
87
+ } else {
88
+ update(
89
+ categories.map((c) =>
90
+ c.id === id ? { ...c, name: value, custom: false } : c,
91
+ ),
92
+ );
93
+ }
94
+ }
95
+
96
+ function handleCustomName(id: string, name: string) {
97
+ update(categories.map((c) => (c.id === id ? { ...c, name } : c)));
98
+ }
99
+
100
+ function handleToggle(id: string, field: "requiredMain" | "requiredCo") {
101
+ update(
102
+ categories.map((c) => (c.id === id ? { ...c, [field]: !c[field] } : c)),
103
+ );
104
+ }
105
+
106
+ function handleDelete(id: string) {
107
+ update(categories.filter((c) => c.id !== id));
108
+ }
109
+
110
+ function handleAdd() {
111
+ update([
112
+ ...categories,
113
+ {
114
+ id: `cat-${Date.now()}`,
115
+ name: "",
116
+ requiredMain: true,
117
+ requiredCo: false,
118
+ custom: false,
119
+ },
120
+ ]);
121
+ }
122
+
123
+ const COLS = "grid-cols-[20px_1fr_64px_64px_32px]";
124
+
125
+ return (
126
+ <div className={cn("flex flex-col", className)}>
127
+ {/* ── Header — title only ── */}
128
+ <div className="shrink-0 border-b border-border px-6 py-4">
129
+ <span className="text-label-large text-foreground">
130
+ Document Checklist Template
131
+ </span>
132
+ </div>
133
+
134
+ {/* ── Description ── */}
135
+ <div className="shrink-0 border-b border-border px-6 py-3">
136
+ <p className="text-body-small text-muted-foreground">
137
+ Define the document categories required for loan applications. Set
138
+ required status separately for Main and Co-applicants.
139
+ </p>
140
+ </div>
141
+
142
+ {/* ── Body ── */}
143
+ <div className="flex flex-col overflow-y-auto">
144
+ {/* Column headers */}
145
+ {categories.length > 0 && (
146
+ <div
147
+ className={cn(
148
+ "grid shrink-0 items-center gap-3 border-b border-border bg-muted/30 px-6 py-2",
149
+ COLS,
150
+ )}
151
+ >
152
+ <span />
153
+ <span className="text-xs font-medium text-muted-foreground">
154
+ Category Name
155
+ </span>
156
+ <span className="text-center text-xs font-medium text-muted-foreground">
157
+ Main
158
+ </span>
159
+ <span className="text-center text-xs font-medium text-muted-foreground">
160
+ Co
161
+ </span>
162
+ <span />
163
+ </div>
164
+ )}
165
+
166
+ {/* Rows */}
167
+ {categories.length === 0 ? (
168
+ <div className="flex items-center justify-center py-12 text-sm text-muted-foreground">
169
+ No categories yet. Add one below.
170
+ </div>
171
+ ) : (
172
+ <div className="divide-y divide-border">
173
+ {categories.map((cat) => (
174
+ <div
175
+ key={cat.id}
176
+ className={cn("grid items-center gap-3 px-6 py-3", COLS)}
177
+ >
178
+ <GripVertical className="size-4 shrink-0 text-muted-foreground/30" />
179
+
180
+ {/* Name: Select (predefined) or Input (custom) */}
181
+ {cat.custom ? (
182
+ <Input
183
+ value={cat.name}
184
+ onChange={(e) => handleCustomName(cat.id, e.target.value)}
185
+ placeholder="Type category name…"
186
+ className="h-8 text-sm"
187
+ autoFocus
188
+ />
189
+ ) : (
190
+ <Select
191
+ value={cat.name || ""}
192
+ onValueChange={(v) => handleSelectType(cat.id, v)}
193
+ >
194
+ <SelectTrigger size="sm" className="w-full">
195
+ <SelectValue placeholder="Select type…" />
196
+ </SelectTrigger>
197
+ <SelectContent>
198
+ {DOCUMENT_TYPES.map((type) => (
199
+ <SelectItem key={type} value={type}>
200
+ {type}
201
+ </SelectItem>
202
+ ))}
203
+ <SelectItem value="__custom__">Custom…</SelectItem>
204
+ </SelectContent>
205
+ </Select>
206
+ )}
207
+
208
+ <div className="flex justify-center">
209
+ <Switch
210
+ checked={cat.requiredMain}
211
+ onCheckedChange={() => handleToggle(cat.id, "requiredMain")}
212
+ size="sm"
213
+ />
214
+ </div>
215
+
216
+ <div className="flex justify-center">
217
+ <Switch
218
+ checked={cat.requiredCo}
219
+ onCheckedChange={() => handleToggle(cat.id, "requiredCo")}
220
+ size="sm"
221
+ />
222
+ </div>
223
+
224
+ <Button
225
+ variant="ghost"
226
+ size="icon"
227
+ className="size-8 text-muted-foreground hover:text-destructive"
228
+ onClick={() => handleDelete(cat.id)}
229
+ >
230
+ <Trash2 className="size-4" />
231
+ </Button>
232
+ </div>
233
+ ))}
234
+ </div>
235
+ )}
236
+
237
+ {/* Add Category */}
238
+ <div className="border-t border-border px-6 py-4">
239
+ <Button
240
+ variant="outline"
241
+ size="sm"
242
+ className="gap-1.5"
243
+ onClick={handleAdd}
244
+ >
245
+ <Plus className="size-4" />
246
+ Add Category
247
+ </Button>
248
+ </div>
249
+ </div>
250
+
251
+ {/* ── Footer ── */}
252
+ <div className="flex shrink-0 justify-end gap-2 border-t border-border px-6 py-4">
253
+ {onCancel && (
254
+ <Button variant="outline" onClick={onCancel}>
255
+ Cancel
256
+ </Button>
257
+ )}
258
+ <Button onClick={() => onSave?.(categories)} disabled={!isDirty}>
259
+ Save
260
+ </Button>
261
+ </div>
262
+ </div>
263
+ );
264
+ }
@@ -85,8 +85,8 @@ function DrawerContent({
85
85
  // WealthX: no rounded corners (Figma: sharp edges)
86
86
  "data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:border-b",
87
87
  "data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:border-t",
88
- "data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm",
89
- "data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm",
88
+ "data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l",
89
+ "data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r",
90
90
  className,
91
91
  )}
92
92
  data-slot="drawer-content"
@@ -22,6 +22,12 @@ import type { LucideIcon } from "lucide-react";
22
22
  import { cn } from "@/lib/utils";
23
23
  import { formatDateShort } from "@/lib/format-date";
24
24
  import { Badge } from "./badge";
25
+ import {
26
+ Accordion,
27
+ AccordionContent,
28
+ AccordionItem,
29
+ AccordionTrigger,
30
+ } from "./accordion";
25
31
  import { RadioGroup, RadioGroupItem } from "./radio-group";
26
32
  import {
27
33
  FinancialDetailField,
@@ -129,11 +135,16 @@ export function PropertyCard({
129
135
  variant="ghost"
130
136
  aria-expanded={expanded}
131
137
  onClick={() => setExpanded((prev) => !prev)}
132
- className="h-auto w-full justify-start gap-1.5 px-5 py-3 text-left"
138
+ className="h-auto w-full justify-start gap-1.5 px-5 py-3 text-left has-[>svg]:px-5"
133
139
  >
134
- <span className="text-label-medium text-foreground">{address}</span>
135
- {type && <Badge variant="outline">{type}</Badge>}
136
- <span className="flex-1" />
140
+ <span className="flex-1 min-w-0 truncate text-label-medium text-foreground">
141
+ {address}
142
+ </span>
143
+ {type && (
144
+ <Badge className="shrink-0" variant="outline">
145
+ {type}
146
+ </Badge>
147
+ )}
137
148
  <ChevronDown
138
149
  className={cn(
139
150
  "h-5 w-5 shrink-0 text-muted-foreground transition-transform duration-200",
@@ -158,14 +169,16 @@ export function PropertyCard({
158
169
  <div
159
170
  className={cn(
160
171
  "grid gap-5 px-5 py-[15px]",
161
- isLinkedToBank ? "grid-cols-3" : "grid-cols-1",
172
+ isLinkedToBank ? "grid-cols-2" : "grid-cols-1",
162
173
  )}
163
174
  >
164
175
  <FinancialDetailField label="Estimated Value" value={estimated} />
165
176
  {isLinkedToBank && (
166
177
  <>
167
178
  <FinancialDetailField label="Loan Amount" value={loanAmount} />
168
- <FinancialDetailField label="Equity" value={equity} />
179
+ <div className="col-span-2">
180
+ <FinancialDetailField label="Equity" value={equity} />
181
+ </div>
169
182
  </>
170
183
  )}
171
184
  </div>
@@ -622,6 +635,8 @@ export interface AboutCardProps {
622
635
  gender?: string;
623
636
  maritalStatus?: string;
624
637
  numDependants?: string;
638
+ /** Individual dependant records — shows DOB + age for each. */
639
+ dependants?: Array<{ dob: string }>;
625
640
  citizenStatus?: string;
626
641
  residentialAddress?: string;
627
642
  residentialStatus?: string;
@@ -631,6 +646,19 @@ export interface AboutCardProps {
631
646
  passport?: string;
632
647
  propertyInTrust?: string;
633
648
  companyOwnership?: string;
649
+ /** Remove the outer card border. Use when the card is already inside a bordered container. */
650
+ borderless?: boolean;
651
+ }
652
+
653
+ function ageFromDob(dobStr: string): number | null {
654
+ if (!dobStr) return null;
655
+ const dob = new Date(dobStr);
656
+ if (isNaN(dob.getTime())) return null;
657
+ const today = new Date();
658
+ let age = today.getFullYear() - dob.getFullYear();
659
+ const m = today.getMonth() - dob.getMonth();
660
+ if (m < 0 || (m === 0 && today.getDate() < dob.getDate())) age--;
661
+ return age >= 0 ? age : null;
634
662
  }
635
663
 
636
664
  /**
@@ -647,6 +675,7 @@ export function AboutCard({
647
675
  gender,
648
676
  maritalStatus,
649
677
  numDependants,
678
+ dependants,
650
679
  citizenStatus,
651
680
  residentialAddress,
652
681
  residentialStatus,
@@ -656,6 +685,7 @@ export function AboutCard({
656
685
  passport,
657
686
  propertyInTrust,
658
687
  companyOwnership,
688
+ borderless = false,
659
689
  }: AboutCardProps) {
660
690
  const fullName =
661
691
  [title, firstName, lastName].filter(Boolean).join(" ") || "—";
@@ -671,13 +701,36 @@ export function AboutCard({
671
701
  : undefined;
672
702
 
673
703
  return (
674
- <div className="border border-border overflow-hidden">
675
- <div className="grid grid-cols-2 gap-x-8 gap-y-4 px-5 py-4">
704
+ <div
705
+ className={cn(
706
+ "overflow-hidden divide-y divide-border",
707
+ !borderless && "border border-border",
708
+ )}
709
+ >
710
+ {/* Identity — personal details + citizenship documents */}
711
+ <div className="grid grid-cols-4 gap-x-6 gap-y-4 px-5 py-4">
676
712
  <FinancialDetailField label="Full Name" value={fullName} />
677
713
  <FinancialDetailField label="Date of Birth" value={dob || "—"} />
678
714
  <FinancialDetailField label="Gender" value={gender || "—"} />
715
+ <FinancialDetailField
716
+ label="Citizenship"
717
+ value={citizenStatus || "—"}
718
+ />
719
+ <FinancialDetailField
720
+ label="Driver's Licence"
721
+ value={driversLicence || "—"}
722
+ />
723
+ <FinancialDetailField label="Passport" value={passport || "—"} />
724
+ </div>
725
+
726
+ {/* Contact */}
727
+ <div className="grid grid-cols-4 gap-x-6 gap-y-4 px-5 py-4">
679
728
  <FinancialDetailField label="Phone" value={phone || "—"} />
680
729
  <FinancialDetailField label="Email" value={email || "—"} />
730
+ </div>
731
+
732
+ {/* Family — marital status + dependants as a dedicated section */}
733
+ <div className="grid grid-cols-4 gap-x-6 gap-y-4 px-5 py-4">
681
734
  <FinancialDetailField
682
735
  label="Marital Status"
683
736
  value={maritalStatus || "—"}
@@ -686,14 +739,30 @@ export function AboutCard({
686
739
  label="No. of Dependants"
687
740
  value={numDependants ?? "—"}
688
741
  />
689
- <FinancialDetailField
690
- label="Citizenship"
691
- value={citizenStatus || "—"}
692
- />
693
- <FinancialDetailField
694
- label="Residential Address"
695
- value={residentialAddress || "—"}
696
- />
742
+ {dependants &&
743
+ dependants.map((dep, i) => {
744
+ const age = ageFromDob(dep.dob);
745
+ const dobFormatted = formatDateShort(dep.dob) || "—";
746
+ const value =
747
+ age !== null ? `${dobFormatted} · age ${age}` : dobFormatted;
748
+ return (
749
+ <FinancialDetailField
750
+ key={i}
751
+ label={`Dependant ${i + 1}`}
752
+ value={value}
753
+ />
754
+ );
755
+ })}
756
+ </div>
757
+
758
+ {/* Residence */}
759
+ <div className="grid grid-cols-4 gap-x-6 gap-y-4 px-5 py-4">
760
+ <div className="col-span-2">
761
+ <FinancialDetailField
762
+ label="Residential Address"
763
+ value={residentialAddress || "—"}
764
+ />
765
+ </div>
697
766
  <FinancialDetailField
698
767
  label="Residential Status"
699
768
  value={residentialStatus || "—"}
@@ -701,11 +770,10 @@ export function AboutCard({
701
770
  {timeAtAddress && (
702
771
  <FinancialDetailField label="Time at Address" value={timeAtAddress} />
703
772
  )}
704
- <FinancialDetailField
705
- label="Driver's Licence"
706
- value={driversLicence || "—"}
707
- />
708
- <FinancialDetailField label="Passport" value={passport || "—"} />
773
+ </div>
774
+
775
+ {/* Ownership */}
776
+ <div className="grid grid-cols-4 gap-x-6 gap-y-4 px-5 py-4">
709
777
  <FinancialDetailField
710
778
  label="Property in Trust"
711
779
  value={propertyInTrust || "—"}
@@ -740,73 +808,92 @@ export interface IncomeCardProps {
740
808
  items: IncomeCardItem[];
741
809
  /** Pre-formatted total monthly income e.g. "$12,300" */
742
810
  totalMonthly?: string;
811
+ /** Remove the outer card border. Use when the card is already inside a bordered container. */
812
+ borderless?: boolean;
743
813
  }
744
814
 
745
-
746
815
  /**
747
816
  * Display card for applicant income items.
748
- * Each income source renders as a bordered row with type, company, and amount.
817
+ * Each income source is an accordion row: collapsed = type + amount,
818
+ * expanded = full employment details.
749
819
  */
750
- export function IncomeCard({ items, totalMonthly }: IncomeCardProps) {
820
+ export function IncomeCard({
821
+ items,
822
+ totalMonthly,
823
+ borderless = false,
824
+ }: IncomeCardProps) {
751
825
  if (items.length === 0) {
752
826
  return (
753
- <div className="border border-border px-5 py-4">
827
+ <div className={cn("px-5 py-4", !borderless && "border border-border")}>
754
828
  <p className="text-sm text-muted-foreground">No income recorded.</p>
755
829
  </div>
756
830
  );
757
831
  }
758
832
 
759
833
  return (
760
- <div className="border border-border overflow-hidden flex flex-col">
761
- {items.map((item, i) => (
762
- <div
763
- key={i}
764
- className={cn(
765
- "flex flex-col gap-3 px-5 py-[15px]",
766
- i < items.length - 1 && "border-b border-border",
767
- )}
768
- >
769
- {/* Primary row: Type | Job Title | Amount */}
770
- <div className="grid grid-cols-3 gap-x-6">
771
- <FinancialDetailField label="Type" value={item.incomeType || "—"} />
772
- <FinancialDetailField
773
- label="Job Title"
774
- value={item.jobTitle || "—"}
775
- />
776
- <FinancialDetailField label="Amount" value={item.amountLabel} />
777
- </div>
778
- {/* Secondary row: Company | Start Date | Status */}
779
- <div className="grid grid-cols-3 gap-x-6">
780
- <FinancialDetailField
781
- label="Company"
782
- value={item.companyName || "—"}
783
- />
784
- <FinancialDetailField
785
- label="Start Date"
786
- value={formatDateShort(item.startDate)}
787
- />
788
- <FinancialDetailField
789
- label="Status"
790
- value={
791
- item.stillInPosition === undefined
792
- ? "—"
793
- : item.stillInPosition
794
- ? "Still in position"
795
- : item.endDate
796
- ? `Ended ${formatDateShort(item.endDate)}`
797
- : "No longer in position"
798
- }
799
- />
800
- </div>
801
- {/* Company address — full width if present */}
802
- {item.companyAddress && (
803
- <FinancialDetailField
804
- label="Company Address"
805
- value={item.companyAddress}
806
- />
807
- )}
808
- </div>
809
- ))}
834
+ <div
835
+ className={cn(
836
+ "overflow-hidden flex flex-col",
837
+ !borderless && "border border-border",
838
+ )}
839
+ >
840
+ <Accordion openMultiple>
841
+ {items.map((item, i) => (
842
+ <AccordionItem key={i} value={String(i)}>
843
+ <AccordionTrigger className="px-5">
844
+ <div className="flex flex-1 items-center justify-between pr-2">
845
+ <div className="flex items-center gap-2">
846
+ <span className="text-label-medium text-foreground">
847
+ {item.incomeType}
848
+ </span>
849
+ {item.jobTitle && (
850
+ <span className="text-body-small text-muted-foreground">
851
+ · {item.jobTitle}
852
+ </span>
853
+ )}
854
+ </div>
855
+ <span className="text-label-medium text-foreground">
856
+ {item.amountLabel}
857
+ </span>
858
+ </div>
859
+ </AccordionTrigger>
860
+ <AccordionContent className="px-5">
861
+ <div className="grid grid-cols-3 gap-x-6 gap-y-4 pb-2 pt-1">
862
+ <FinancialDetailField
863
+ label="Job Title"
864
+ value={item.jobTitle || "—"}
865
+ />
866
+ <FinancialDetailField
867
+ label="Company"
868
+ value={item.companyName || "—"}
869
+ />
870
+ <FinancialDetailField
871
+ label="Start Date"
872
+ value={formatDateShort(item.startDate)}
873
+ />
874
+ <FinancialDetailField
875
+ label="Status"
876
+ value={
877
+ item.stillInPosition === undefined
878
+ ? "—"
879
+ : item.stillInPosition
880
+ ? "Still in position"
881
+ : item.endDate
882
+ ? `Ended ${formatDateShort(item.endDate)}`
883
+ : "No longer in position"
884
+ }
885
+ />
886
+ {item.companyAddress && (
887
+ <FinancialDetailField
888
+ label="Company Address"
889
+ value={item.companyAddress}
890
+ />
891
+ )}
892
+ </div>
893
+ </AccordionContent>
894
+ </AccordionItem>
895
+ ))}
896
+ </Accordion>
810
897
  {totalMonthly && (
811
898
  <FinancialSubtotalFrame>
812
899
  <FinancialSubtotalBlock
@@ -865,23 +952,34 @@ export interface ExpensesCardProps {
865
952
  items: ExpensesCardItem[];
866
953
  /** Pre-formatted total monthly expenses e.g. "$2,100" */
867
954
  totalMonthly?: string;
955
+ /** Remove the outer card border. Use when the card is already inside a bordered container. */
956
+ borderless?: boolean;
868
957
  }
869
958
 
870
959
  /**
871
960
  * Display card for applicant expense items.
872
961
  * Each expense renders as an icon-labelled row with a destructive amount value.
873
962
  */
874
- export function ExpensesCard({ items, totalMonthly }: ExpensesCardProps) {
963
+ export function ExpensesCard({
964
+ items,
965
+ totalMonthly,
966
+ borderless = false,
967
+ }: ExpensesCardProps) {
875
968
  if (items.length === 0) {
876
969
  return (
877
- <div className="border border-border px-5 py-4">
970
+ <div className={cn("px-5 py-4", !borderless && "border border-border")}>
878
971
  <p className="text-sm text-muted-foreground">No expenses recorded.</p>
879
972
  </div>
880
973
  );
881
974
  }
882
975
 
883
976
  return (
884
- <div className="border border-border overflow-hidden flex flex-col">
977
+ <div
978
+ className={cn(
979
+ "overflow-hidden flex flex-col",
980
+ !borderless && "border border-border",
981
+ )}
982
+ >
885
983
  <div className="flex flex-col">
886
984
  {items.map((item, i) => {
887
985
  const Icon = getExpenseIcon(item.expenseType);
@@ -106,7 +106,7 @@ export function SummaryReportDrawer({
106
106
  showCloseButton={false}
107
107
  className="w-[min(1080px,90vw)] max-w-none p-0"
108
108
  >
109
- <div className="flex max-h-[100dvh] min-h-0 flex-1 flex-col overflow-hidden px-8 py-6">
109
+ <div className="flex max-h-[100dvh] min-h-0 flex-1 flex-col gap-4 overflow-hidden px-8 py-6">
110
110
  {/* ── Header chrome ── */}
111
111
  <div className="shrink-0 space-y-4">
112
112
  <div className="flex flex-col gap-3">
@@ -147,7 +147,7 @@ export function SummaryReportDrawer({
147
147
  {contactName} View
148
148
  </span>
149
149
  <Button
150
- variant="outline"
150
+ variant="outline-secondary"
151
151
  size="sm"
152
152
  onClick={onCreateJointView}
153
153
  >
@@ -83,7 +83,7 @@ export function PropertyHoldingsSection({
83
83
  {items.map((item, i) => (
84
84
  <div
85
85
  key={`${item.address}-${i}`}
86
- className={i > 0 ? "border-l border-border pl-5" : "pr-5"}
86
+ className={i % 2 !== 0 ? "border-l border-border pl-5" : "pr-5"}
87
87
  >
88
88
  <PropertyCard {...item} borderless />
89
89
  </div>