@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
@@ -42,6 +42,8 @@ export interface AppointmentAvailabilityPrefs {
42
42
  meetingDuration: string;
43
43
  schedulingBuffer: string;
44
44
  maxSlotsPerDay: string;
45
+ /** IANA timezone identifier — e.g. "Australia/Sydney" */
46
+ timezone: string;
45
47
  }
46
48
 
47
49
  export interface AppointmentBlockedDate {
@@ -56,8 +58,29 @@ export interface AppointmentBlockedDate {
56
58
  }
57
59
 
58
60
  export interface AppointmentAvailabilitySettingsProps {
61
+ /**
62
+ * Initial weekly schedule.
63
+ * @remarks Mount-time initialiser only — prop changes after mount are ignored.
64
+ * Use the `key` prop to reset the component when async data arrives.
65
+ */
59
66
  schedule: AppointmentDaySchedule[];
67
+ /**
68
+ * Saved booking preferences from DB — initialises the Booking Preferences tab.
69
+ * @remarks Mount-time initialiser only.
70
+ */
71
+ prefs?: AppointmentAvailabilityPrefs;
72
+ /**
73
+ * Custom blocked dates added by the user (non-holiday).
74
+ * Merged with `publicHolidays` in the Time Off tab.
75
+ * @remarks Mount-time initialiser only.
76
+ */
60
77
  blockedDates?: AppointmentBlockedDate[];
78
+ /**
79
+ * Public holiday list from the DB/API.
80
+ * When provided, replaces the built-in `AU_PUBLIC_HOLIDAYS_2026` fallback.
81
+ * @remarks Mount-time initialiser only.
82
+ */
83
+ publicHolidays?: AppointmentBlockedDate[];
61
84
  onSave?: (
62
85
  schedule: AppointmentDaySchedule[],
63
86
  prefs: AppointmentAvailabilityPrefs,
@@ -66,9 +89,10 @@ export interface AppointmentAvailabilitySettingsProps {
66
89
  }
67
90
 
68
91
  // ---------------------------------------------------------------------------
69
- // AU Public Holidays 2026
92
+ // Constants
70
93
  // ---------------------------------------------------------------------------
71
94
 
95
+ /** Fallback holiday list used when the `publicHolidays` prop is not provided. */
72
96
  const AU_PUBLIC_HOLIDAYS_2026: AppointmentBlockedDate[] = [
73
97
  { date: "2026-01-01", label: "New Year's Day" },
74
98
  { date: "2026-01-26", label: "Australia Day" },
@@ -81,23 +105,19 @@ const AU_PUBLIC_HOLIDAYS_2026: AppointmentBlockedDate[] = [
81
105
  { date: "2026-12-26", label: "Boxing Day" },
82
106
  ];
83
107
 
84
- // ---------------------------------------------------------------------------
85
- // Internal type Time Off entries with switch state
86
- // ---------------------------------------------------------------------------
87
-
88
- interface TimeOffEntry {
89
- date: string;
90
- label?: string;
91
- enabled: boolean;
92
- isHoliday: boolean;
93
- timeStart?: string;
94
- timeEnd?: string;
95
- }
96
-
97
- // ---------------------------------------------------------------------------
98
- // Time options — 30-min increments from 6:00 to 21:30
99
- // ---------------------------------------------------------------------------
108
+ export const TIMEZONE_OPTIONS: { value: string; label: string }[] = [
109
+ { value: "Australia/Sydney", label: "Sydney / Melbourne (AEDT)" },
110
+ { value: "Australia/Brisbane", label: "Brisbane (AEST, no DST)" },
111
+ { value: "Australia/Adelaide", label: "Adelaide (ACDT)" },
112
+ { value: "Australia/Perth", label: "Perth (AWST)" },
113
+ { value: "Australia/Darwin", label: "Darwin (ACST, no DST)" },
114
+ { value: "Australia/Hobart", label: "Hobart (AEDT)" },
115
+ { value: "Asia/Ho_Chi_Minh", label: "Ho Chi Minh City (ICT)" },
116
+ { value: "Asia/Singapore", label: "Singapore (SGT)" },
117
+ { value: "UTC", label: "UTC" },
118
+ ];
100
119
 
120
+ // 30-min increments from 06:00 to 21:30
101
121
  const TIME_OPTIONS: { value: string; label: string }[] = (() => {
102
122
  const opts: { value: string; label: string }[] = [];
103
123
  for (let h = 6; h <= 21; h++) {
@@ -115,6 +135,23 @@ const TIME_OPTIONS: { value: string; label: string }[] = (() => {
115
135
  const timeLabel = (v: string) =>
116
136
  TIME_OPTIONS.find((o) => o.value === v)?.label ?? v;
117
137
 
138
+ // ---------------------------------------------------------------------------
139
+ // Internal type
140
+ // ---------------------------------------------------------------------------
141
+
142
+ interface TimeOffEntry {
143
+ date: string;
144
+ label?: string;
145
+ enabled: boolean;
146
+ isHoliday: boolean;
147
+ timeStart?: string;
148
+ timeEnd?: string;
149
+ }
150
+
151
+ // ---------------------------------------------------------------------------
152
+ // Sub-components
153
+ // ---------------------------------------------------------------------------
154
+
118
155
  function TimeSelect({
119
156
  value,
120
157
  onChange,
@@ -144,10 +181,26 @@ function TimeSelect({
144
181
  );
145
182
  }
146
183
 
147
-
148
- // ---------------------------------------------------------------------------
149
- // "Add More" dialog
150
- // ---------------------------------------------------------------------------
184
+ /** Shared row layout for the Booking Preferences tab. */
185
+ function PrefRow({
186
+ label,
187
+ description,
188
+ children,
189
+ }: {
190
+ label: string;
191
+ description: string;
192
+ children: React.ReactNode;
193
+ }) {
194
+ return (
195
+ <div className="flex min-h-[68px] items-center justify-between px-6 py-4">
196
+ <div className="flex flex-col gap-0.5">
197
+ <p className="text-sm font-medium">{label}</p>
198
+ <p className="text-xs text-muted-foreground">{description}</p>
199
+ </div>
200
+ {children}
201
+ </div>
202
+ );
203
+ }
151
204
 
152
205
  function AddTimeOffDialog({
153
206
  open,
@@ -156,12 +209,7 @@ function AddTimeOffDialog({
156
209
  }: {
157
210
  open: boolean;
158
211
  onOpenChange: (v: boolean) => void;
159
- onAdd: (entry: {
160
- date: string;
161
- label?: string;
162
- timeStart?: string;
163
- timeEnd?: string;
164
- }) => void;
212
+ onAdd: (entry: AppointmentBlockedDate) => void;
165
213
  }) {
166
214
  const [label, setLabel] = React.useState("");
167
215
  const [date, setDate] = React.useState<Date | undefined>(undefined);
@@ -179,7 +227,6 @@ function AddTimeOffDialog({
179
227
 
180
228
  const handleAdd = () => {
181
229
  if (!date) return;
182
- // Convert Date to ISO date string "YYYY-MM-DD"
183
230
  const isoDate = [
184
231
  date.getFullYear(),
185
232
  String(date.getMonth() + 1).padStart(2, "0"),
@@ -212,7 +259,6 @@ function AddTimeOffDialog({
212
259
  </DialogHeader>
213
260
 
214
261
  <div className="flex flex-col gap-4 py-1">
215
- {/* Label */}
216
262
  <div className="flex flex-col gap-1.5">
217
263
  <Label htmlFor="toff-label">
218
264
  Name{" "}
@@ -228,7 +274,6 @@ function AddTimeOffDialog({
228
274
  />
229
275
  </div>
230
276
 
231
- {/* Date */}
232
277
  <div className="flex flex-col gap-1.5">
233
278
  <Label>Date</Label>
234
279
  <DatePicker
@@ -239,7 +284,6 @@ function AddTimeOffDialog({
239
284
  />
240
285
  </div>
241
286
 
242
- {/* Add time switch */}
243
287
  <div className="flex flex-col gap-3">
244
288
  <div className="flex items-center gap-3">
245
289
  <Switch
@@ -284,30 +328,33 @@ function AddTimeOffDialog({
284
328
 
285
329
  export function AppointmentAvailabilitySettings({
286
330
  schedule: initialSchedule,
331
+ prefs: prefsProp,
287
332
  blockedDates: blockedDatesProp,
333
+ publicHolidays: publicHolidaysProp,
288
334
  onSave,
289
335
  onBlockedDatesChange,
290
336
  }: AppointmentAvailabilitySettingsProps) {
291
- // Track first render to skip auto-save on mount
292
- const hasMounted = React.useRef(false);
293
- React.useEffect(() => {
294
- hasMounted.current = true;
295
- }, []);
296
-
297
- // --- Weekly Availability tab ---
298
337
  const [schedule, setSchedule] =
299
338
  React.useState<AppointmentDaySchedule[]>(initialSchedule);
300
339
 
301
- // --- Booking Preferences tab ---
302
- const [meetingDuration, setMeetingDuration] = React.useState("30");
303
- const [schedulingBuffer, setSchedulingBuffer] = React.useState("0");
304
- const [maxSlotsPerDay, setMaxSlotsPerDay] = React.useState("8");
340
+ const [meetingDuration, setMeetingDuration] = React.useState(
341
+ prefsProp?.meetingDuration ?? "30",
342
+ );
343
+ const [schedulingBuffer, setSchedulingBuffer] = React.useState(
344
+ prefsProp?.schedulingBuffer ?? "0",
345
+ );
346
+ const [maxSlotsPerDay, setMaxSlotsPerDay] = React.useState(
347
+ prefsProp?.maxSlotsPerDay ?? "8",
348
+ );
349
+ const [timezone, setTimezone] = React.useState(
350
+ prefsProp?.timezone ?? "Australia/Sydney",
351
+ );
305
352
 
306
- // --- Time Off tab ---
307
353
  const [timeOffEntries, setTimeOffEntries] = React.useState<TimeOffEntry[]>(
308
354
  () => {
309
- const holidayDates = new Set(AU_PUBLIC_HOLIDAYS_2026.map((h) => h.date));
310
- const entries: TimeOffEntry[] = AU_PUBLIC_HOLIDAYS_2026.map((h) => ({
355
+ const holidays = publicHolidaysProp ?? AU_PUBLIC_HOLIDAYS_2026;
356
+ const holidayDates = new Set(holidays.map((h) => h.date));
357
+ const entries: TimeOffEntry[] = holidays.map((h) => ({
311
358
  ...h,
312
359
  enabled: true,
313
360
  isHoliday: true,
@@ -328,28 +375,36 @@ export function AppointmentAvailabilitySettings({
328
375
  const [addMoreOpen, setAddMoreOpen] = React.useState(false);
329
376
 
330
377
  // ---------------------------------------------------------------------------
331
- // Auto-save — fires after each deliberate state change (skip initial mount)
378
+ // Auto-save effects
379
+ //
380
+ // Each effect uses its own mount-guard ref. A shared ref would break because
381
+ // React runs effects in declaration order within the same flush — the first
382
+ // effect would flip the ref to `true`, causing later effects to skip their
383
+ // own guard and fire onSave/onBlockedDatesChange on mount.
332
384
  // ---------------------------------------------------------------------------
333
385
 
334
386
  const currentPrefs = React.useMemo(
335
- () => ({ meetingDuration, schedulingBuffer, maxSlotsPerDay }),
336
- [meetingDuration, schedulingBuffer, maxSlotsPerDay],
387
+ () => ({ meetingDuration, schedulingBuffer, maxSlotsPerDay, timezone }),
388
+ [meetingDuration, schedulingBuffer, maxSlotsPerDay, timezone],
337
389
  );
338
390
 
339
- React.useEffect(() => {
340
- if (!hasMounted.current) return;
341
- onSave?.(schedule, currentPrefs);
342
- // eslint-disable-next-line react-hooks/exhaustive-deps
343
- }, [schedule]);
391
+ const saveGuard = React.useRef(false);
392
+ const timeOffGuard = React.useRef(false);
344
393
 
345
394
  React.useEffect(() => {
346
- if (!hasMounted.current) return;
395
+ if (!saveGuard.current) {
396
+ saveGuard.current = true;
397
+ return;
398
+ }
347
399
  onSave?.(schedule, currentPrefs);
348
400
  // eslint-disable-next-line react-hooks/exhaustive-deps
349
- }, [meetingDuration, schedulingBuffer, maxSlotsPerDay]);
401
+ }, [schedule, currentPrefs]);
350
402
 
351
403
  React.useEffect(() => {
352
- if (!hasMounted.current) return;
404
+ if (!timeOffGuard.current) {
405
+ timeOffGuard.current = true;
406
+ return;
407
+ }
353
408
  const blocked = timeOffEntries
354
409
  .filter((e) => e.enabled)
355
410
  .map(({ date, label, timeStart, timeEnd }) => ({
@@ -363,7 +418,7 @@ export function AppointmentAvailabilitySettings({
363
418
  }, [timeOffEntries]);
364
419
 
365
420
  // ---------------------------------------------------------------------------
366
- // Weekly handlers
421
+ // Weekly schedule handlers
367
422
  // ---------------------------------------------------------------------------
368
423
 
369
424
  const toggleDay = (index: number) => {
@@ -396,12 +451,7 @@ export function AppointmentAvailabilitySettings({
396
451
  setTimeOffEntries((prev) => prev.filter((e) => e.date !== date));
397
452
  };
398
453
 
399
- const handleAddMore = (entry: {
400
- date: string;
401
- label?: string;
402
- timeStart?: string;
403
- timeEnd?: string;
404
- }) => {
454
+ const handleAddMore = (entry: AppointmentBlockedDate) => {
405
455
  if (timeOffEntries.some((e) => e.date === entry.date)) return;
406
456
  setTimeOffEntries((prev) =>
407
457
  [
@@ -421,7 +471,6 @@ export function AppointmentAvailabilitySettings({
421
471
  return (
422
472
  <div className="border border-border bg-card">
423
473
  <Tabs defaultValue="weekly" className="gap-0">
424
- {/* Tab strip */}
425
474
  <div className="border-b border-border p-1">
426
475
  <TabsList variant="default" className="w-full">
427
476
  <TabsTrigger value="weekly">Weekly Availability</TabsTrigger>
@@ -430,9 +479,7 @@ export function AppointmentAvailabilitySettings({
430
479
  </TabsList>
431
480
  </div>
432
481
 
433
- {/* ---------------------------------------------------------------- */}
434
- {/* Tab 1: Weekly Availability */}
435
- {/* ---------------------------------------------------------------- */}
482
+ {/* Tab 1: Weekly Availability */}
436
483
  <TabsContent value="weekly">
437
484
  <div className="flex flex-col divide-y divide-border">
438
485
  {schedule.map((day, index) => (
@@ -476,18 +523,13 @@ export function AppointmentAvailabilitySettings({
476
523
  </div>
477
524
  </TabsContent>
478
525
 
479
- {/* ---------------------------------------------------------------- */}
480
- {/* Tab 2: Booking Preferences */}
481
- {/* ---------------------------------------------------------------- */}
526
+ {/* Tab 2: Booking Preferences */}
482
527
  <TabsContent value="booking">
483
528
  <div className="flex flex-col divide-y divide-border">
484
- <div className="flex min-h-[68px] items-center justify-between px-6 py-4">
485
- <div className="flex flex-col gap-0.5">
486
- <p className="text-sm font-medium">Meeting Duration</p>
487
- <p className="text-xs text-muted-foreground">
488
- Length of each appointment slot
489
- </p>
490
- </div>
529
+ <PrefRow
530
+ label="Meeting Duration"
531
+ description="Length of each appointment slot"
532
+ >
491
533
  <Select
492
534
  value={meetingDuration}
493
535
  onValueChange={(v) => setMeetingDuration(v as string)}
@@ -503,15 +545,12 @@ export function AppointmentAvailabilitySettings({
503
545
  <SelectItem value="90">90 minutes</SelectItem>
504
546
  </SelectContent>
505
547
  </Select>
506
- </div>
548
+ </PrefRow>
507
549
 
508
- <div className="flex min-h-[68px] items-center justify-between px-6 py-4">
509
- <div className="flex flex-col gap-0.5">
510
- <p className="text-sm font-medium">Scheduling Buffer</p>
511
- <p className="text-xs text-muted-foreground">
512
- Gap between consecutive bookings
513
- </p>
514
- </div>
550
+ <PrefRow
551
+ label="Scheduling Buffer"
552
+ description="Gap between consecutive bookings"
553
+ >
515
554
  <Select
516
555
  value={schedulingBuffer}
517
556
  onValueChange={(v) => setSchedulingBuffer(v as string)}
@@ -527,15 +566,12 @@ export function AppointmentAvailabilitySettings({
527
566
  <SelectItem value="30">30 minutes</SelectItem>
528
567
  </SelectContent>
529
568
  </Select>
530
- </div>
569
+ </PrefRow>
531
570
 
532
- <div className="flex min-h-[68px] items-center justify-between px-6 py-4">
533
- <div className="flex flex-col gap-0.5">
534
- <p className="text-sm font-medium">Daily Slot Limit</p>
535
- <p className="text-xs text-muted-foreground">
536
- Maximum bookings accepted per day
537
- </p>
538
- </div>
571
+ <PrefRow
572
+ label="Daily Slot Limit"
573
+ description="Maximum bookings accepted per day"
574
+ >
539
575
  <Select
540
576
  value={maxSlotsPerDay}
541
577
  onValueChange={(v) => setMaxSlotsPerDay(v as string)}
@@ -552,15 +588,33 @@ export function AppointmentAvailabilitySettings({
552
588
  <SelectItem value="unlimited">Unlimited</SelectItem>
553
589
  </SelectContent>
554
590
  </Select>
555
- </div>
591
+ </PrefRow>
592
+
593
+ <PrefRow
594
+ label="Meeting Timezone"
595
+ description="Timezone used for booking display and notifications"
596
+ >
597
+ <Select
598
+ value={timezone}
599
+ onValueChange={(v) => setTimezone(v as string)}
600
+ >
601
+ <SelectTrigger className="w-56">
602
+ <SelectValue />
603
+ </SelectTrigger>
604
+ <SelectContent>
605
+ {TIMEZONE_OPTIONS.map((opt) => (
606
+ <SelectItem key={opt.value} value={opt.value}>
607
+ {opt.label}
608
+ </SelectItem>
609
+ ))}
610
+ </SelectContent>
611
+ </Select>
612
+ </PrefRow>
556
613
  </div>
557
614
  </TabsContent>
558
615
 
559
- {/* ---------------------------------------------------------------- */}
560
- {/* Tab 3: Time Off */}
561
- {/* ---------------------------------------------------------------- */}
616
+ {/* Tab 3: Time Off */}
562
617
  <TabsContent value="time-off">
563
- {/* Description + Add more button */}
564
618
  <div className="flex items-center justify-between px-6 py-4">
565
619
  <p className="text-sm text-muted-foreground">
566
620
  Toggle dates when you are unavailable. Clients cannot book on
@@ -579,7 +633,6 @@ export function AppointmentAvailabilitySettings({
579
633
 
580
634
  <Separator />
581
635
 
582
- {/* Holiday + custom date rows */}
583
636
  <div className="flex flex-col divide-y divide-border">
584
637
  {timeOffEntries.map((entry) => {
585
638
  const formattedDate = formatDateWithWeekday(entry.date);
@@ -615,7 +668,6 @@ export function AppointmentAvailabilitySettings({
615
668
  )}
616
669
  </p>
617
670
  </div>
618
- {/* Only custom (non-holiday) dates can be removed */}
619
671
  {!entry.isHoliday && (
620
672
  <Button
621
673
  type="button"
@@ -634,7 +686,6 @@ export function AppointmentAvailabilitySettings({
634
686
  </TabsContent>
635
687
  </Tabs>
636
688
 
637
- {/* Add More dialog */}
638
689
  <AddTimeOffDialog
639
690
  open={addMoreOpen}
640
691
  onOpenChange={setAddMoreOpen}