@wealthx/shadcn 1.3.2 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (313) hide show
  1. package/.turbo/turbo-build.log +262 -226
  2. package/CHANGELOG.md +6 -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-3OYFOX3X.mjs → chunk-5VOTTIXF.mjs} +2 -2
  14. package/dist/{chunk-LBMRIB3G.mjs → chunk-6AJUS7VX.mjs} +1 -1
  15. package/dist/{chunk-OODBHKG7.mjs → chunk-6HIOM2HL.mjs} +7 -4
  16. package/dist/{chunk-BDYZCBRT.mjs → chunk-6QAFGZC2.mjs} +2 -2
  17. package/dist/{chunk-U4NDAF2P.mjs → chunk-6TX73WG7.mjs} +1 -1
  18. package/dist/{chunk-GD4BJDJR.mjs → chunk-7BTFGCFC.mjs} +4 -4
  19. package/dist/{chunk-FAKPBKLT.mjs → chunk-7GWRPXHD.mjs} +4 -4
  20. package/dist/{chunk-NMOI6CQD.mjs → chunk-7YI3HEBH.mjs} +5 -5
  21. package/dist/{chunk-T4BJLT57.mjs → chunk-AE7MASLF.mjs} +5 -5
  22. package/dist/{chunk-VLQZANBF.mjs → chunk-AFML43VJ.mjs} +6 -1
  23. package/dist/chunk-BBXSNDS3.mjs +260 -0
  24. package/dist/chunk-BOW7U26Y.mjs +203 -0
  25. package/dist/{chunk-34NWQURD.mjs → chunk-BS75ICOO.mjs} +2 -2
  26. package/dist/chunk-D2NSIIXG.mjs +394 -0
  27. package/dist/{chunk-3GF7OVTP.mjs → chunk-DGNHGNYH.mjs} +2 -2
  28. package/dist/{chunk-VLARHE5V.mjs → chunk-DMXYRCHM.mjs} +6 -6
  29. package/dist/{chunk-OGOYQ7BG.mjs → chunk-DQB4EPIS.mjs} +1 -1
  30. package/dist/{chunk-MIZQHHUO.mjs → chunk-FL6DZFJK.mjs} +106 -38
  31. package/dist/{chunk-I3RZS7V2.mjs → chunk-FLL633WS.mjs} +19 -33
  32. package/dist/{chunk-PBL4OQV2.mjs → chunk-FTPBQVQ6.mjs} +4 -4
  33. package/dist/chunk-FYPSTTEJ.mjs +169 -0
  34. package/dist/{chunk-6O6KD7CE.mjs → chunk-G27TSQLQ.mjs} +6 -6
  35. package/dist/{chunk-66MI7Q4B.mjs → chunk-GT3RU6GA.mjs} +2 -2
  36. package/dist/{chunk-D6ID6M4V.mjs → chunk-GTAVSBDO.mjs} +2 -2
  37. package/dist/{chunk-24FUO7TD.mjs → chunk-H6NQTIF4.mjs} +2 -2
  38. package/dist/{chunk-7DHU4VGG.mjs → chunk-HK4HUQTV.mjs} +2 -2
  39. package/dist/chunk-I4KVSZCH.mjs +101 -0
  40. package/dist/{chunk-RGVKLTLH.mjs → chunk-IKXYTCSB.mjs} +2 -2
  41. package/dist/{chunk-Y6DWJSKZ.mjs → chunk-ISUA7DSB.mjs} +1 -1
  42. package/dist/{chunk-2A5RRQGG.mjs → chunk-JD3YWRNP.mjs} +10 -14
  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 +157 -152
  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 +12764 -9396
  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 +10 -14
  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,70 @@
1
+ import * as React from "react";
2
+ import { Check, X } from "lucide-react";
3
+ import {
4
+ Popover,
5
+ PopoverContent,
6
+ PopoverTrigger,
7
+ } from "@/components/ui/popover";
8
+
9
+ type ValidationRule = { label: string; test: (p: string) => boolean };
10
+
11
+ const RULES: ValidationRule[] = [
12
+ { label: "Minimum 8 characters", test: (p) => p.length >= 8 },
13
+ { label: "At least one uppercase letter", test: (p) => /[A-Z]/.test(p) },
14
+ { label: "At least one lowercase letter", test: (p) => /[a-z]/.test(p) },
15
+ { label: "At least one number", test: (p) => /\d/.test(p) },
16
+ {
17
+ label: "At least one special character",
18
+ test: (p) => /[^A-Za-z0-9]/.test(p),
19
+ },
20
+ ];
21
+
22
+ export type PasswordStrengthTooltipProps = {
23
+ open?: boolean;
24
+ password: string;
25
+ children: React.ReactNode;
26
+ side?: "top" | "right" | "bottom" | "left";
27
+ };
28
+
29
+ export function PasswordStrengthTooltip({
30
+ open = false,
31
+ password,
32
+ children,
33
+ side = "right",
34
+ }: PasswordStrengthTooltipProps) {
35
+ return (
36
+ <Popover open={open}>
37
+ <PopoverTrigger asChild>
38
+ <div>{children}</div>
39
+ </PopoverTrigger>
40
+ <PopoverContent
41
+ side={side}
42
+ align="start"
43
+ sideOffset={8}
44
+ onOpenAutoFocus={(e) => e.preventDefault()}
45
+ className="w-auto max-w-[280px] font-sans"
46
+ >
47
+ <div className="flex flex-col gap-1.5">
48
+ {RULES.map((rule) => {
49
+ const valid = password ? rule.test(password) : false;
50
+ return (
51
+ <div
52
+ key={rule.label}
53
+ className={`flex items-center gap-1.5 text-[13px] leading-[18px] ${
54
+ valid ? "text-success" : "text-destructive"
55
+ }`}
56
+ >
57
+ {valid ? (
58
+ <Check size={14} className="shrink-0" />
59
+ ) : (
60
+ <X size={14} className="shrink-0" />
61
+ )}
62
+ <span>{rule.label}</span>
63
+ </div>
64
+ );
65
+ })}
66
+ </div>
67
+ </PopoverContent>
68
+ </Popover>
69
+ );
70
+ }
@@ -1,6 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { cn } from "@/lib/utils";
3
3
  import { useThemeVars } from "@/lib/theme-provider";
4
+ import { formatCurrencyAbbrev } from "@/lib/format-currency";
4
5
 
5
6
  /**
6
7
  * PipelineChart — WealthX DS (L4 Section)
@@ -40,12 +41,7 @@ export interface PipelineChartProps {
40
41
  // ---------------------------------------------------------------------------
41
42
 
42
43
  function formatValue(v: number): string {
43
- return new Intl.NumberFormat("en-AU", {
44
- style: "currency",
45
- currency: "AUD",
46
- notation: "compact",
47
- maximumFractionDigits: 1,
48
- }).format(v);
44
+ return formatCurrencyAbbrev(v);
49
45
  }
50
46
 
51
47
  // Fallback palette (used when stage.color is not set) — uses stage vars so
@@ -24,7 +24,7 @@ import {
24
24
  } from "lucide-react";
25
25
  import type { LucideIcon } from "lucide-react";
26
26
  import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion";
27
- import { cn } from "@/lib/utils";
27
+ import { cn, getInitials } from "@/lib/utils";
28
28
  import { formatCurrency } from "@/lib/format-currency";
29
29
  import { Accordion, AccordionContent, AccordionItem } from "./accordion";
30
30
  import { Button } from "./button";
@@ -100,16 +100,6 @@ export interface SidebarNavProps {
100
100
 
101
101
  // ─── Helpers ───────────────────────────────────────────────────────────────────
102
102
 
103
- function getInitials(name: string): string {
104
- return name
105
- .split(" ")
106
- .filter(Boolean)
107
- .map((word) => word[0])
108
- .join("")
109
- .toUpperCase()
110
- .slice(0, 2);
111
- }
112
-
113
103
  function navIconCn(isActive: boolean): string {
114
104
  return cn(
115
105
  "shrink-0 transition-colors",
@@ -0,0 +1,229 @@
1
+ import * as React from "react";
2
+ import { useState } from "react";
3
+ import { Smartphone } from "lucide-react";
4
+ import { Button } from "@/components/ui/button";
5
+ import { Field, FieldError } from "@/components/ui/field";
6
+ import { InputGroup, InputGroupInput } from "@/components/ui/input-group";
7
+ import { Label } from "@/components/ui/label";
8
+ import { cn } from "@/lib/utils";
9
+
10
+ // ─── Types ────────────────────────────────────────────────────────────────────
11
+
12
+ export type TwoFAApp = {
13
+ name: string;
14
+ icon?: React.ReactNode;
15
+ qrNode?: React.ReactNode;
16
+ };
17
+
18
+ export type TwoFASetupFormProps = {
19
+ title?: string;
20
+ apps?: TwoFAApp[];
21
+ qrCodeNode?: React.ReactNode;
22
+ onVerify: (token: string) => Promise<void>;
23
+ onSetupLater?: () => void;
24
+ required?: boolean;
25
+ className?: string;
26
+ };
27
+
28
+ const DEFAULT_APPS: TwoFAApp[] = [
29
+ { name: "Google Authenticator" },
30
+ { name: "Microsoft Authenticator" },
31
+ ];
32
+
33
+ // ─── AppDownloadStep ─────────────────────────────────────────────────────────
34
+
35
+ function AppDownloadStep({
36
+ apps,
37
+ onNext,
38
+ onSetupLater,
39
+ required,
40
+ }: {
41
+ apps: TwoFAApp[];
42
+ onNext: () => void;
43
+ onSetupLater?: () => void;
44
+ required?: boolean;
45
+ }) {
46
+ return (
47
+ <div className="flex flex-col gap-6">
48
+ <div className="flex gap-4">
49
+ {apps.map((app) => (
50
+ <div
51
+ key={app.name}
52
+ className="flex flex-1 flex-col items-center gap-3 border border-border bg-muted/30 p-4 text-center"
53
+ >
54
+ <div className="flex items-center gap-2 text-sm font-medium text-foreground">
55
+ {app.icon ?? (
56
+ <Smartphone size={18} className="text-muted-foreground" />
57
+ )}
58
+ {app.name}
59
+ </div>
60
+ {app.qrNode ? (
61
+ <div className="flex items-center justify-center">
62
+ {app.qrNode}
63
+ </div>
64
+ ) : (
65
+ <div className="flex h-[100px] w-[100px] items-center justify-center border border-dashed border-border bg-muted/50 text-[11px] text-muted-foreground">
66
+ Scan to download
67
+ </div>
68
+ )}
69
+ </div>
70
+ ))}
71
+ </div>
72
+
73
+ <p className="text-center text-sm text-muted-foreground">
74
+ Once downloaded, or if you already have the app installed, click Next.
75
+ </p>
76
+
77
+ <div className="flex flex-col gap-2">
78
+ <Button className="w-full" onClick={onNext}>
79
+ Next
80
+ </Button>
81
+ {!required && onSetupLater && (
82
+ <Button variant="ghost" className="w-full" onClick={onSetupLater}>
83
+ Setup Later
84
+ </Button>
85
+ )}
86
+ </div>
87
+ </div>
88
+ );
89
+ }
90
+
91
+ // ─── VerificationStep ────────────────────────────────────────────────────────
92
+
93
+ function VerificationStep({
94
+ qrCodeNode,
95
+ onVerify,
96
+ onBack,
97
+ onSetupLater,
98
+ required,
99
+ }: {
100
+ qrCodeNode?: React.ReactNode;
101
+ onVerify: (token: string) => Promise<void>;
102
+ onBack: () => void;
103
+ onSetupLater?: () => void;
104
+ required?: boolean;
105
+ }) {
106
+ const [token, setToken] = useState("");
107
+ const [error, setError] = useState("");
108
+ const [isLoading, setIsLoading] = useState(false);
109
+
110
+ const handleVerify = async () => {
111
+ if (!token) {
112
+ setError("Required");
113
+ return;
114
+ }
115
+ setError("");
116
+ setIsLoading(true);
117
+ try {
118
+ await onVerify(token);
119
+ } catch {
120
+ setError("Invalid code. Please try again.");
121
+ } finally {
122
+ setIsLoading(false);
123
+ }
124
+ };
125
+
126
+ return (
127
+ <div className="flex flex-col gap-6">
128
+ <div className="flex flex-col items-center gap-3">
129
+ {qrCodeNode ? (
130
+ <div className="flex items-center justify-center">{qrCodeNode}</div>
131
+ ) : (
132
+ <div className="flex h-[140px] w-[140px] items-center justify-center border border-dashed border-border bg-muted/50 text-xs text-muted-foreground">
133
+ QR Code
134
+ </div>
135
+ )}
136
+ <p className="text-center text-sm text-muted-foreground">
137
+ The temporary code will show for authentication. Insert below.
138
+ </p>
139
+ </div>
140
+
141
+ <Field>
142
+ <Label htmlFor="2fa-token">Verification Code</Label>
143
+ <InputGroup>
144
+ <InputGroupInput
145
+ id="2fa-token"
146
+ type="text"
147
+ name="token"
148
+ placeholder="Enter Your Code"
149
+ value={token}
150
+ aria-invalid={!!error}
151
+ onChange={(e) => {
152
+ setToken(e.target.value);
153
+ if (error) setError("");
154
+ }}
155
+ onKeyDown={(e) => {
156
+ if (e.key === "Enter") handleVerify();
157
+ }}
158
+ />
159
+ </InputGroup>
160
+ {error && <FieldError>{error}</FieldError>}
161
+ </Field>
162
+
163
+ <div className="flex flex-col gap-2">
164
+ <Button
165
+ loading={isLoading}
166
+ disabled={!token}
167
+ className="w-full"
168
+ onClick={handleVerify}
169
+ >
170
+ Verify Now
171
+ </Button>
172
+ <Button variant="outline" className="w-full" onClick={onBack}>
173
+ Back
174
+ </Button>
175
+ {!required && onSetupLater && (
176
+ <Button variant="ghost" className="w-full" onClick={onSetupLater}>
177
+ Setup Later
178
+ </Button>
179
+ )}
180
+ </div>
181
+ </div>
182
+ );
183
+ }
184
+
185
+ // ─── TwoFASetupForm ───────────────────────────────────────────────────────────
186
+
187
+ export function TwoFASetupForm({
188
+ title = "2FA Setup",
189
+ apps = DEFAULT_APPS,
190
+ qrCodeNode,
191
+ onVerify,
192
+ onSetupLater,
193
+ required = true,
194
+ className,
195
+ }: TwoFASetupFormProps) {
196
+ const [step, setStep] = useState<1 | 2>(1);
197
+
198
+ const stepTitle = step === 1 ? title : "Open Auth App and Scan Code";
199
+ const stepSubtitle =
200
+ step === 1
201
+ ? "We recommend Google Authenticator or Microsoft Authenticator"
202
+ : "Open your authenticator app and scan the QR code";
203
+
204
+ return (
205
+ <div className={cn("flex flex-col gap-6", className)}>
206
+ <div className="flex flex-col gap-1">
207
+ <h2 className="text-xl font-semibold text-foreground">{stepTitle}</h2>
208
+ <p className="text-sm text-muted-foreground">{stepSubtitle}</p>
209
+ </div>
210
+
211
+ {step === 1 ? (
212
+ <AppDownloadStep
213
+ apps={apps}
214
+ onNext={() => setStep(2)}
215
+ onSetupLater={onSetupLater}
216
+ required={required}
217
+ />
218
+ ) : (
219
+ <VerificationStep
220
+ qrCodeNode={qrCodeNode}
221
+ onVerify={onVerify}
222
+ onBack={() => setStep(1)}
223
+ onSetupLater={onSetupLater}
224
+ required={required}
225
+ />
226
+ )}
227
+ </div>
228
+ );
229
+ }
@@ -0,0 +1,98 @@
1
+ import * as React from "react";
2
+ import { UploadIcon } from "lucide-react";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+ import { cn } from "@/lib/utils";
5
+
6
+ /**
7
+ * UploadCard — WealthX DS
8
+ *
9
+ * A dashed-border upload zone used in forms that accept file input.
10
+ * Comes in two sizes:
11
+ * - `sm` — compact, fixed max-width (e.g. logo / photo uploads)
12
+ * - `lg` — full-width, taller drop zone (e.g. bulk CSV upload)
13
+ *
14
+ * WealthX overrides:
15
+ * - No border-radius — sharp corners per WealthX DS
16
+ */
17
+
18
+ const uploadCardVariants = cva(
19
+ [
20
+ "flex flex-col items-center justify-center gap-2",
21
+ "border border-dashed border-border",
22
+ "cursor-pointer text-muted-foreground",
23
+ "hover:bg-muted/50 bg-muted/20 transition-colors",
24
+ ],
25
+ {
26
+ variants: {
27
+ size: {
28
+ sm: "w-[200px] py-4 px-3",
29
+ lg: "w-full py-8 px-6",
30
+ },
31
+ },
32
+ defaultVariants: {
33
+ size: "sm",
34
+ },
35
+ },
36
+ );
37
+
38
+ export type UploadCardProps = React.ComponentProps<"label"> &
39
+ VariantProps<typeof uploadCardVariants> & {
40
+ /** Label text shown below the upload icon */
41
+ label?: string;
42
+ /** Helper text shown below the label */
43
+ description?: string;
44
+ /** File types to accept, passed to the hidden <input> */
45
+ accept?: string;
46
+ /** Called when the user selects a file */
47
+ onFileChange?: (file: File | null) => void;
48
+ };
49
+
50
+ function UploadCard({
51
+ label = "Upload image",
52
+ description,
53
+ accept = ".png,.jpg,.jpeg",
54
+ size,
55
+ onFileChange,
56
+ className,
57
+ ...props
58
+ }: UploadCardProps) {
59
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
60
+ onFileChange?.(e.target.files?.[0] ?? null);
61
+ };
62
+
63
+ return (
64
+ <label
65
+ className={cn(uploadCardVariants({ size }), className)}
66
+ data-slot="upload-card"
67
+ data-size={size ?? "sm"}
68
+ {...props}
69
+ >
70
+ <UploadIcon
71
+ className={cn("text-primary", size === "lg" ? "size-6" : "size-4")}
72
+ />
73
+ <span
74
+ className={cn("font-medium", size === "lg" ? "text-sm" : "text-xs")}
75
+ >
76
+ {label}
77
+ </span>
78
+ {description && (
79
+ <p
80
+ className={cn(
81
+ "text-center leading-relaxed",
82
+ size === "lg" ? "text-sm" : "text-xs",
83
+ )}
84
+ >
85
+ {description}
86
+ </p>
87
+ )}
88
+ <input
89
+ type="file"
90
+ accept={accept}
91
+ className="sr-only"
92
+ onChange={handleChange}
93
+ />
94
+ </label>
95
+ );
96
+ }
97
+
98
+ export { UploadCard, uploadCardVariants };
@@ -0,0 +1,55 @@
1
+ import * as React from "react";
2
+ import { cn } from "@/lib/utils";
3
+
4
+ export type VideoBackgroundProps = {
5
+ src?: string;
6
+ poster?: string;
7
+ overlay?: "light" | "medium" | "dark";
8
+ children?: React.ReactNode;
9
+ className?: string;
10
+ };
11
+
12
+ export function VideoBackground({
13
+ src,
14
+ poster,
15
+ overlay = "medium",
16
+ children,
17
+ className,
18
+ }: VideoBackgroundProps) {
19
+ const overlayClass = {
20
+ light: "bg-black/25",
21
+ medium: "bg-black/50",
22
+ dark: "bg-black/70",
23
+ }[overlay];
24
+
25
+ return (
26
+ <div
27
+ className={cn(
28
+ "relative min-h-screen w-full overflow-hidden bg-neutral-900",
29
+ className,
30
+ )}
31
+ >
32
+ {src && (
33
+ <video
34
+ className="absolute inset-0 h-full w-full object-cover"
35
+ autoPlay
36
+ muted
37
+ loop
38
+ playsInline
39
+ poster={poster}
40
+ src={src}
41
+ />
42
+ )}
43
+ {!src && poster && (
44
+ <img
45
+ className="absolute inset-0 h-full w-full object-cover"
46
+ src={poster}
47
+ alt=""
48
+ aria-hidden="true"
49
+ />
50
+ )}
51
+ <div className={cn("absolute inset-0", overlayClass)} />
52
+ <div className="relative z-10">{children}</div>
53
+ </div>
54
+ );
55
+ }
@@ -48,3 +48,29 @@ export function formatDateWithWeekday(iso: string): string {
48
48
  return iso;
49
49
  }
50
50
  }
51
+
52
+ /**
53
+ * Format a Date or ISO string as "Monday, 15 January" (long weekday + day + long month).
54
+ * Returns raw string on parse failure.
55
+ */
56
+ export function formatDateLong(date: Date | string): string {
57
+ try {
58
+ const d = typeof date === "string" ? safeParse(date) : date;
59
+ return format(d, "EEEE, d MMMM");
60
+ } catch {
61
+ return String(date);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Format a Date or ISO string as an uppercase short weekday: "MON", "TUE", etc.
67
+ * Returns raw string on parse failure.
68
+ */
69
+ export function formatWeekdayShort(date: Date | string): string {
70
+ try {
71
+ const d = typeof date === "string" ? safeParse(date) : date;
72
+ return format(d, "EEE").toUpperCase();
73
+ } catch {
74
+ return String(date);
75
+ }
76
+ }
package/src/lib/utils.ts CHANGED
@@ -42,3 +42,14 @@ const twMerge = extendTailwindMerge({
42
42
  export function cn(...inputs: ClassValue[]): string {
43
43
  return twMerge(clsx(inputs));
44
44
  }
45
+
46
+ export function getInitials(name: string): string {
47
+ if (!name.trim()) return "?";
48
+ return name
49
+ .split(" ")
50
+ .filter(Boolean)
51
+ .map((word) => word[0])
52
+ .join("")
53
+ .toUpperCase()
54
+ .slice(0, 2);
55
+ }