@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,1268 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __getProtoOf = Object.getPrototypeOf;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b || (b = {}))
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ var __objRest = (source, exclude) => {
26
+ var target = {};
27
+ for (var prop in source)
28
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
29
+ target[prop] = source[prop];
30
+ if (source != null && __getOwnPropSymbols)
31
+ for (var prop of __getOwnPropSymbols(source)) {
32
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
33
+ target[prop] = source[prop];
34
+ }
35
+ return target;
36
+ };
37
+ var __export = (target, all) => {
38
+ for (var name in all)
39
+ __defProp(target, name, { get: all[name], enumerable: true });
40
+ };
41
+ var __copyProps = (to, from, except, desc) => {
42
+ if (from && typeof from === "object" || typeof from === "function") {
43
+ for (let key of __getOwnPropNames(from))
44
+ if (!__hasOwnProp.call(to, key) && key !== except)
45
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
46
+ }
47
+ return to;
48
+ };
49
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
50
+ // If the importer is in node compatibility mode or this is not an ESM
51
+ // file that has been converted to a CommonJS file using a Babel-
52
+ // compatible transform (i.e. "__esModule" has not been set), then set
53
+ // "default" to the CommonJS "module.exports" for node compatibility.
54
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
55
+ mod
56
+ ));
57
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
58
+
59
+ // src/components/ui/chat-widget.tsx
60
+ var chat_widget_exports = {};
61
+ __export(chat_widget_exports, {
62
+ ChatWidget: () => ChatWidget,
63
+ ChatWidgetIntakeForm: () => ChatWidgetIntakeForm,
64
+ ChatWidgetInteractiveCard: () => ChatWidgetInteractiveCard,
65
+ ChatWidgetTopicCard: () => ChatWidgetTopicCard,
66
+ ChatWidgetTopicGrid: () => ChatWidgetTopicGrid,
67
+ ChatWidgetWindow: () => ChatWidgetWindow,
68
+ DEFAULT_CHAT_WIDGET_TOPICS: () => DEFAULT_CHAT_WIDGET_TOPICS
69
+ });
70
+ module.exports = __toCommonJS(chat_widget_exports);
71
+ var import_react3 = __toESM(require("react"));
72
+ var import_lucide_react3 = require("lucide-react");
73
+
74
+ // src/lib/utils.ts
75
+ var import_clsx = require("clsx");
76
+ var import_tailwind_merge = require("tailwind-merge");
77
+ var twMerge = (0, import_tailwind_merge.extendTailwindMerge)({
78
+ extend: {
79
+ classGroups: {
80
+ "font-size": [
81
+ {
82
+ text: [
83
+ "display-large",
84
+ "display-medium",
85
+ "display-small",
86
+ "h1",
87
+ "h2",
88
+ "h3",
89
+ "h4",
90
+ "h5",
91
+ "h6",
92
+ "body-large",
93
+ "body-medium",
94
+ "body-small",
95
+ "label-large",
96
+ "label-medium",
97
+ "label-small",
98
+ "button",
99
+ "button-xs",
100
+ "caption",
101
+ "overline",
102
+ "code"
103
+ ]
104
+ }
105
+ ]
106
+ }
107
+ }
108
+ });
109
+ function cn(...inputs) {
110
+ return twMerge((0, import_clsx.clsx)(inputs));
111
+ }
112
+
113
+ // src/components/ui/button.tsx
114
+ var import_react = require("react");
115
+ var import_class_variance_authority = require("class-variance-authority");
116
+ var import_lucide_react = require("lucide-react");
117
+
118
+ // src/lib/slot.tsx
119
+ var React = __toESM(require("react"));
120
+ function mergeRefs(...refs) {
121
+ return (value) => {
122
+ for (const ref of refs) {
123
+ if (typeof ref === "function") ref(value);
124
+ else if (ref !== null)
125
+ ref.current = value;
126
+ }
127
+ };
128
+ }
129
+ var Slot = React.forwardRef(
130
+ (_a, forwardedRef) => {
131
+ var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
132
+ const child = React.Children.only(children);
133
+ if (!React.isValidElement(child)) return null;
134
+ const childProps = child.props;
135
+ const merged = __spreadValues({}, props);
136
+ for (const key of Object.keys(childProps)) {
137
+ if (key === "className") {
138
+ merged.className = [props.className, childProps.className].filter(Boolean).join(" ");
139
+ } else if (key === "style") {
140
+ merged.style = __spreadValues(__spreadValues({}, props.style), childProps.style);
141
+ } else if (key.startsWith("on") && typeof childProps[key] === "function") {
142
+ const parentHandler = props[key];
143
+ if (typeof parentHandler === "function") {
144
+ merged[key] = (...args) => {
145
+ childProps[key](...args);
146
+ parentHandler(...args);
147
+ };
148
+ } else {
149
+ merged[key] = childProps[key];
150
+ }
151
+ } else {
152
+ merged[key] = childProps[key];
153
+ }
154
+ }
155
+ const childRef = child.ref;
156
+ merged.ref = forwardedRef ? mergeRefs(forwardedRef, childRef) : childRef;
157
+ return React.cloneElement(
158
+ child,
159
+ merged
160
+ );
161
+ }
162
+ );
163
+ Slot.displayName = "Slot";
164
+
165
+ // src/components/ui/button.tsx
166
+ var import_jsx_runtime = require("react/jsx-runtime");
167
+ var buttonVariants = (0, import_class_variance_authority.cva)(
168
+ "inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 font-sans text-button whitespace-nowrap transition-all active:scale-[0.98] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
169
+ {
170
+ variants: {
171
+ variant: {
172
+ default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
173
+ secondary: "bg-brand-secondary text-brand-secondary-foreground shadow-xs hover:bg-brand-secondary/80 focus-visible:ring-brand-secondary/30",
174
+ destructive: "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
175
+ outline: "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground focus-visible:border-border focus-visible:ring-border/50 dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
176
+ "outline-primary": "border border-primary text-foreground bg-transparent shadow-xs hover:bg-primary/5 focus-visible:ring-primary/50",
177
+ "outline-secondary": "border border-brand-secondary text-brand-secondary bg-transparent shadow-xs hover:bg-brand-secondary/10 focus-visible:border-brand-secondary focus-visible:ring-brand-secondary/30",
178
+ ghost: "hover:bg-accent hover:text-accent-foreground hover:shadow-xs focus-visible:ring-border/50 dark:hover:bg-accent/50",
179
+ link: "text-primary underline-offset-4 hover:underline"
180
+ },
181
+ size: {
182
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
183
+ xs: "h-6 gap-1 px-2 text-button-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
184
+ sm: "h-8 gap-1.5 px-3 has-[>svg]:px-2.5",
185
+ lg: "h-10 px-6 has-[>svg]:px-4",
186
+ icon: "size-9",
187
+ "icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
188
+ "icon-sm": "size-8",
189
+ "icon-lg": "size-10"
190
+ }
191
+ },
192
+ defaultVariants: {
193
+ variant: "default",
194
+ size: "default"
195
+ }
196
+ }
197
+ );
198
+ var Button = (0, import_react.forwardRef)(function Button2(_a, ref) {
199
+ var _b = _a, {
200
+ className,
201
+ variant,
202
+ size,
203
+ asChild = false,
204
+ loading = false,
205
+ disabled,
206
+ type = "button",
207
+ children
208
+ } = _b, props = __objRest(_b, [
209
+ "className",
210
+ "variant",
211
+ "size",
212
+ "asChild",
213
+ "loading",
214
+ "disabled",
215
+ "type",
216
+ "children"
217
+ ]);
218
+ const Comp = asChild ? Slot : "button";
219
+ const isIconOnly = size === "icon" || size === "icon-xs" || size === "icon-sm" || size === "icon-lg";
220
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
221
+ Comp,
222
+ __spreadProps(__spreadValues({
223
+ className: cn(buttonVariants({ variant, size, className })),
224
+ "data-size": size,
225
+ "data-slot": "button",
226
+ "data-variant": variant,
227
+ disabled: loading || disabled,
228
+ ref,
229
+ type
230
+ }, props), {
231
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
232
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { "aria-hidden": "true", className: "animate-spin" }),
233
+ !isIconOnly && children
234
+ ] }) : children
235
+ })
236
+ );
237
+ });
238
+
239
+ // src/components/ui/input.tsx
240
+ var import_jsx_runtime2 = require("react/jsx-runtime");
241
+ function Input(_a) {
242
+ var _b = _a, { className, type } = _b, props = __objRest(_b, ["className", "type"]);
243
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
244
+ "input",
245
+ __spreadValues({
246
+ className: cn(
247
+ "h-9 w-full min-w-0 border border-input bg-transparent px-3 py-1 text-body-medium font-sans shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-label-medium file:text-foreground placeholder:font-normal placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input/30",
248
+ "focus-visible:border-primary focus-visible:ring-[3px] focus-visible:ring-primary/20",
249
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
250
+ className
251
+ ),
252
+ "data-slot": "input",
253
+ type
254
+ }, props)
255
+ );
256
+ }
257
+
258
+ // src/components/ui/field.tsx
259
+ var import_react2 = require("react");
260
+ var import_class_variance_authority2 = require("class-variance-authority");
261
+
262
+ // src/components/ui/label.tsx
263
+ var import_jsx_runtime3 = (
264
+ // eslint-disable-next-line jsx-a11y/label-has-associated-control -- htmlFor is passed by the consumer
265
+ require("react/jsx-runtime")
266
+ );
267
+ function Label(_a) {
268
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
269
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
270
+ "label",
271
+ __spreadValues({
272
+ className: cn(
273
+ "flex items-center gap-2 text-label-medium leading-none select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
274
+ className
275
+ ),
276
+ "data-slot": "label"
277
+ }, props)
278
+ );
279
+ }
280
+
281
+ // src/components/ui/separator.tsx
282
+ var import_separator = require("@base-ui/react/separator");
283
+ var import_jsx_runtime4 = require("react/jsx-runtime");
284
+
285
+ // src/components/ui/field.tsx
286
+ var import_jsx_runtime5 = require("react/jsx-runtime");
287
+ var fieldVariants = (0, import_class_variance_authority2.cva)(
288
+ "group/field flex w-full gap-3 data-[invalid=true]:text-destructive",
289
+ {
290
+ variants: {
291
+ orientation: {
292
+ vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
293
+ horizontal: [
294
+ "flex-row items-center",
295
+ "[&>[data-slot=field-label]]:flex-auto",
296
+ "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px"
297
+ ],
298
+ responsive: [
299
+ "flex-col @md/field-group:flex-row @md/field-group:items-center [&>*]:w-full @md/field-group:[&>*]:w-auto [&>.sr-only]:w-auto",
300
+ "@md/field-group:[&>[data-slot=field-label]]:flex-auto",
301
+ "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px"
302
+ ]
303
+ }
304
+ },
305
+ defaultVariants: {
306
+ orientation: "vertical"
307
+ }
308
+ }
309
+ );
310
+ function Field(_a) {
311
+ var _b = _a, {
312
+ className,
313
+ orientation = "vertical"
314
+ } = _b, props = __objRest(_b, [
315
+ "className",
316
+ "orientation"
317
+ ]);
318
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
319
+ "div",
320
+ __spreadValues({
321
+ className: cn(fieldVariants({ orientation }), className),
322
+ "data-orientation": orientation,
323
+ "data-slot": "field",
324
+ role: "group"
325
+ }, props)
326
+ );
327
+ }
328
+ function FieldLabel(_a) {
329
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
330
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
331
+ Label,
332
+ __spreadValues({
333
+ className: cn(
334
+ "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
335
+ "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
336
+ "has-data-checked:border-primary has-data-checked:bg-primary/5 dark:has-data-checked:bg-primary/10",
337
+ className
338
+ ),
339
+ "data-slot": "field-label"
340
+ }, props)
341
+ );
342
+ }
343
+ function FieldError(_a) {
344
+ var _b = _a, {
345
+ className,
346
+ children,
347
+ errors
348
+ } = _b, props = __objRest(_b, [
349
+ "className",
350
+ "children",
351
+ "errors"
352
+ ]);
353
+ const content = (0, import_react2.useMemo)(() => {
354
+ var _a2;
355
+ if (children) {
356
+ return children;
357
+ }
358
+ if (!(errors == null ? void 0 : errors.length)) {
359
+ return null;
360
+ }
361
+ const uniqueErrors = Array.from(
362
+ new Map(errors.map((error) => [error == null ? void 0 : error.message, error])).values()
363
+ );
364
+ if (uniqueErrors.length === 1) {
365
+ return (_a2 = uniqueErrors[0]) == null ? void 0 : _a2.message;
366
+ }
367
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { className: "ml-4 flex list-disc flex-col gap-1", children: uniqueErrors.map(
368
+ (error) => (error == null ? void 0 : error.message) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: error.message }, error.message)
369
+ ) });
370
+ }, [children, errors]);
371
+ if (!content) {
372
+ return null;
373
+ }
374
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
375
+ "div",
376
+ __spreadProps(__spreadValues({
377
+ className: cn("text-caption text-destructive", className),
378
+ "data-slot": "field-error",
379
+ role: "alert"
380
+ }, props), {
381
+ children: content
382
+ })
383
+ );
384
+ }
385
+
386
+ // src/components/ui/chat-widget-primitives.tsx
387
+ var import_lucide_react2 = require("lucide-react");
388
+
389
+ // src/components/ui/avatar.tsx
390
+ var import_avatar = require("@base-ui/react/avatar");
391
+ var import_jsx_runtime6 = require("react/jsx-runtime");
392
+ function Avatar(_a) {
393
+ var _b = _a, {
394
+ className,
395
+ size = "default"
396
+ } = _b, props = __objRest(_b, [
397
+ "className",
398
+ "size"
399
+ ]);
400
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
401
+ import_avatar.Avatar.Root,
402
+ __spreadValues({
403
+ className: cn(
404
+ "group/avatar relative flex size-8 shrink-0 rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
405
+ className
406
+ ),
407
+ "data-size": size,
408
+ "data-slot": "avatar"
409
+ }, props)
410
+ );
411
+ }
412
+ function AvatarFallback(_a) {
413
+ var _b = _a, {
414
+ className
415
+ } = _b, props = __objRest(_b, [
416
+ "className"
417
+ ]);
418
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
419
+ import_avatar.Avatar.Fallback,
420
+ __spreadValues({
421
+ className: cn(
422
+ "flex size-full items-center justify-center rounded-full overflow-hidden bg-muted text-body-small font-sans text-muted-foreground group-data-[size=sm]/avatar:text-caption",
423
+ className
424
+ ),
425
+ "data-slot": "avatar-fallback"
426
+ }, props)
427
+ );
428
+ }
429
+
430
+ // src/components/ui/badge.tsx
431
+ var import_class_variance_authority3 = require("class-variance-authority");
432
+ var import_jsx_runtime7 = require("react/jsx-runtime");
433
+ var badgeVariants = (0, import_class_variance_authority3.cva)(
434
+ "inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2.5 py-0.5 text-xs font-medium font-sans whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3",
435
+ {
436
+ variants: {
437
+ variant: {
438
+ default: "border-primary/40 bg-primary/10 text-foreground [a&]:hover:bg-primary/15",
439
+ secondary: "border-border bg-muted text-muted-foreground [a&]:hover:bg-muted/80",
440
+ destructive: "border-destructive/40 bg-destructive/10 text-destructive-text focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/15",
441
+ success: "border-success/40 bg-success/10 text-success-text [a&]:hover:bg-success/15",
442
+ warning: "border-warning/40 bg-warning/10 text-warning-text [a&]:hover:bg-warning/15",
443
+ info: "border-info/40 bg-info/10 text-info-text [a&]:hover:bg-info/15",
444
+ outline: "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
445
+ ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
446
+ link: "text-primary underline-offset-4 [a&]:hover:underline"
447
+ }
448
+ },
449
+ defaultVariants: {
450
+ variant: "default"
451
+ }
452
+ }
453
+ );
454
+ function Badge(_a) {
455
+ var _b = _a, {
456
+ className,
457
+ variant = "default",
458
+ asChild = false
459
+ } = _b, props = __objRest(_b, [
460
+ "className",
461
+ "variant",
462
+ "asChild"
463
+ ]);
464
+ const Comp = asChild ? Slot : "span";
465
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
466
+ Comp,
467
+ __spreadValues({
468
+ className: cn(badgeVariants({ variant }), className),
469
+ "data-slot": "badge",
470
+ "data-variant": variant
471
+ }, props)
472
+ );
473
+ }
474
+
475
+ // src/components/ui/chat-widget-primitives.tsx
476
+ var import_jsx_runtime8 = require("react/jsx-runtime");
477
+ function ChatWidgetLauncher({
478
+ isOpen,
479
+ onClick,
480
+ brandColor,
481
+ unreadCount,
482
+ className
483
+ }) {
484
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
485
+ "button",
486
+ {
487
+ type: "button",
488
+ "aria-label": isOpen ? "Close chat" : "Open chat",
489
+ onClick,
490
+ className: cn(
491
+ "relative flex size-14 items-center justify-center shadow-lg transition-all",
492
+ "rounded-full",
493
+ // intentional: circular FAB shape
494
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
495
+ className
496
+ ),
497
+ style: { backgroundColor: brandColor != null ? brandColor : "var(--primary)" },
498
+ children: [
499
+ !isOpen && unreadCount && unreadCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
500
+ Badge,
501
+ {
502
+ variant: "destructive",
503
+ className: "absolute -right-1 -top-1 size-5 justify-center bg-destructive px-0 py-0 text-[10px] font-semibold text-destructive-foreground",
504
+ children: unreadCount > 9 ? "9+" : unreadCount
505
+ }
506
+ ) : null,
507
+ isOpen ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.X, { className: "size-6 text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.MessageCircle, { className: "size-6 text-white" })
508
+ ]
509
+ }
510
+ );
511
+ }
512
+ function ChatWidgetHeader({
513
+ brokerName,
514
+ subtitle = "Feel free to chat with us",
515
+ gradientFrom,
516
+ gradientTo,
517
+ onMinimize,
518
+ className
519
+ }) {
520
+ const hasGradient = gradientFrom && gradientTo;
521
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
522
+ "div",
523
+ {
524
+ className: cn(
525
+ "flex items-start justify-between px-4 py-3",
526
+ !hasGradient && "bg-primary",
527
+ className
528
+ ),
529
+ style: hasGradient ? {
530
+ background: `linear-gradient(135deg, ${gradientFrom}, ${gradientTo})`
531
+ } : void 0,
532
+ children: [
533
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
534
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-body-large font-semibold text-primary-foreground", children: brokerName }),
535
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-body-small text-primary-foreground/70", children: subtitle })
536
+ ] }),
537
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex items-center gap-1", children: onMinimize && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
538
+ Button,
539
+ {
540
+ variant: "ghost",
541
+ size: "icon-sm",
542
+ "aria-label": "Minimize chat",
543
+ onClick: onMinimize,
544
+ className: "text-primary-foreground/70 hover:bg-primary-foreground/10 hover:text-primary-foreground",
545
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.ChevronDown, { className: "size-4" })
546
+ }
547
+ ) })
548
+ ]
549
+ }
550
+ );
551
+ }
552
+ function ChatWidgetMessage({
553
+ role,
554
+ content,
555
+ timestamp,
556
+ isStreaming,
557
+ className
558
+ }) {
559
+ if (role === "system") {
560
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: cn("flex items-center justify-center py-2", className), children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-body-small text-muted-foreground", children: content }) });
561
+ }
562
+ const isLeft = role === "bot" || role === "advisor";
563
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
564
+ "div",
565
+ {
566
+ className: cn(
567
+ "flex gap-2",
568
+ isLeft ? "items-start" : "flex-row-reverse items-start",
569
+ className
570
+ ),
571
+ children: [
572
+ isLeft && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Avatar, { className: "size-7", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
573
+ AvatarFallback,
574
+ {
575
+ className: role === "advisor" ? "bg-primary/15 text-foreground" : void 0,
576
+ children: role === "advisor" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.UserRound, { className: "size-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Bot, { className: "size-3.5" })
577
+ }
578
+ ) }),
579
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
580
+ "div",
581
+ {
582
+ className: cn(
583
+ "flex max-w-[80%] flex-col gap-1",
584
+ !isLeft && "items-end"
585
+ ),
586
+ children: [
587
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
588
+ "div",
589
+ {
590
+ className: cn(
591
+ "px-3 py-2 text-body-medium",
592
+ isLeft ? "border border-border bg-card text-card-foreground shadow-sm" : "text-primary-foreground"
593
+ ),
594
+ style: !isLeft ? { backgroundColor: "var(--primary)" } : void 0,
595
+ children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChatWidgetTypingIndicator, {}) : content
596
+ }
597
+ ),
598
+ timestamp && !isStreaming && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-[10px] text-muted-foreground", children: timestamp })
599
+ ]
600
+ }
601
+ )
602
+ ]
603
+ }
604
+ );
605
+ }
606
+ function ChatWidgetTypingIndicator({
607
+ className
608
+ }) {
609
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
610
+ "div",
611
+ {
612
+ role: "status",
613
+ "aria-label": "Typing",
614
+ className: cn("flex items-center gap-1 py-0.5", className),
615
+ children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
616
+ "span",
617
+ {
618
+ className: "size-1.5 animate-bounce rounded-full bg-muted-foreground/60",
619
+ style: { animationDelay: `${i * 0.15}s` },
620
+ "aria-hidden": "true"
621
+ },
622
+ i
623
+ ))
624
+ }
625
+ );
626
+ }
627
+ function ChatWidgetInputBar({
628
+ value,
629
+ onChange,
630
+ onSend,
631
+ disabled,
632
+ placeholder = "Type your message here",
633
+ className
634
+ }) {
635
+ const hasText = value.trim().length > 0;
636
+ const handleKeyDown = (e) => {
637
+ if (e.key === "Enter" && !e.shiftKey && hasText && !disabled) {
638
+ e.preventDefault();
639
+ onSend(value);
640
+ }
641
+ };
642
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
643
+ "div",
644
+ {
645
+ className: cn(
646
+ "flex items-center gap-2 border-t border-border bg-muted/30 px-3 py-2.5",
647
+ className
648
+ ),
649
+ children: [
650
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
651
+ Button,
652
+ {
653
+ variant: "ghost",
654
+ size: "icon-sm",
655
+ "aria-label": "Add emoji",
656
+ disabled,
657
+ className: "shrink-0 text-muted-foreground hover:text-foreground",
658
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Smile, { className: "size-5" })
659
+ }
660
+ ),
661
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
662
+ Button,
663
+ {
664
+ variant: "ghost",
665
+ size: "icon-sm",
666
+ "aria-label": "Add attachment",
667
+ disabled,
668
+ className: "shrink-0 text-muted-foreground hover:text-foreground",
669
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Paperclip, { className: "size-5" })
670
+ }
671
+ ),
672
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
673
+ Input,
674
+ {
675
+ value,
676
+ onChange: (e) => onChange(e.target.value),
677
+ onKeyDown: handleKeyDown,
678
+ placeholder,
679
+ disabled,
680
+ className: "flex-1 border-0 bg-transparent px-0 shadow-none focus-visible:ring-0 text-body-medium placeholder:text-muted-foreground/60"
681
+ }
682
+ ),
683
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
684
+ Button,
685
+ {
686
+ type: "button",
687
+ variant: "ghost",
688
+ size: "icon-sm",
689
+ "aria-label": "Send message",
690
+ disabled: disabled || !hasText,
691
+ onClick: () => hasText && !disabled && onSend(value),
692
+ className: "shrink-0",
693
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Send, { className: "size-4" })
694
+ }
695
+ )
696
+ ]
697
+ }
698
+ );
699
+ }
700
+
701
+ // src/components/ui/chat-widget.tsx
702
+ var import_jsx_runtime9 = require("react/jsx-runtime");
703
+ var DEFAULT_CHAT_WIDGET_TOPICS = [
704
+ {
705
+ id: "buy_home",
706
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Home, { className: "size-5" }),
707
+ label: "Buy a Home",
708
+ description: "Purchase your first or next property"
709
+ },
710
+ {
711
+ id: "refinance",
712
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.RefreshCw, { className: "size-5" }),
713
+ label: "Refinance",
714
+ description: "Get a better rate on your current loan"
715
+ },
716
+ {
717
+ id: "investment",
718
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.TrendingUp, { className: "size-5" }),
719
+ label: "Investment Property",
720
+ description: "Grow your property portfolio"
721
+ },
722
+ {
723
+ id: "first_home_buyer",
724
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Key, { className: "size-5" }),
725
+ label: "First Home Buyer",
726
+ description: "First home buyer grants & schemes"
727
+ },
728
+ {
729
+ id: "book_meeting",
730
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.CalendarDays, { className: "size-5" }),
731
+ label: "Book a Meeting",
732
+ description: "Talk directly with an advisor"
733
+ },
734
+ {
735
+ id: "general_question",
736
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.HelpCircle, { className: "size-5" }),
737
+ label: "General Question",
738
+ description: "Ask anything about home loans"
739
+ }
740
+ ];
741
+ function ChatWidgetIntakeForm({
742
+ brokerName,
743
+ onSubmit,
744
+ isSubmitting,
745
+ className
746
+ }) {
747
+ const [name, setName] = (0, import_react3.useState)("");
748
+ const [phone, setPhone] = (0, import_react3.useState)("");
749
+ const [email, setEmail] = (0, import_react3.useState)("");
750
+ const [errors, setErrors] = (0, import_react3.useState)({});
751
+ const clearError = (field) => setErrors((prev) => __spreadProps(__spreadValues({}, prev), { [field]: void 0 }));
752
+ const validate = () => {
753
+ const e = {};
754
+ if (!name.trim()) e.name = "Name is required";
755
+ if (!phone.trim()) e.phone = "Phone number is required";
756
+ if (!email.trim()) e.email = "Email is required";
757
+ else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email))
758
+ e.email = "Enter a valid email address";
759
+ return e;
760
+ };
761
+ const handleSubmit = (e) => {
762
+ e.preventDefault();
763
+ const errs = validate();
764
+ if (Object.keys(errs).length > 0) {
765
+ setErrors(errs);
766
+ return;
767
+ }
768
+ onSubmit({ name: name.trim(), phone: phone.trim(), email: email.trim() });
769
+ };
770
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: cn("flex flex-col gap-5 p-5", className), children: [
771
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
772
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-body-large font-semibold text-foreground", children: brokerName ? `Hi from ${brokerName}!` : "Hi there!" }),
773
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "mt-1 text-body-medium text-muted-foreground", children: "To get started, please share your contact details." })
774
+ ] }),
775
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { onSubmit: handleSubmit, noValidate: true, className: "flex flex-col gap-3", children: [
776
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Field, { children: [
777
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(FieldLabel, { children: [
778
+ "Full Name ",
779
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-destructive", children: "*" })
780
+ ] }),
781
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
782
+ Input,
783
+ {
784
+ value: name,
785
+ onChange: (e) => {
786
+ setName(e.target.value);
787
+ clearError("name");
788
+ },
789
+ placeholder: "Jane Smith",
790
+ disabled: isSubmitting,
791
+ "aria-invalid": !!errors.name || void 0
792
+ }
793
+ ),
794
+ errors.name && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FieldError, { children: errors.name })
795
+ ] }),
796
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Field, { children: [
797
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(FieldLabel, { children: [
798
+ "Phone Number ",
799
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-destructive", children: "*" })
800
+ ] }),
801
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
802
+ Input,
803
+ {
804
+ type: "tel",
805
+ value: phone,
806
+ onChange: (e) => {
807
+ setPhone(e.target.value);
808
+ clearError("phone");
809
+ },
810
+ placeholder: "0400 000 000",
811
+ disabled: isSubmitting,
812
+ "aria-invalid": !!errors.phone || void 0
813
+ }
814
+ ),
815
+ errors.phone && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FieldError, { children: errors.phone })
816
+ ] }),
817
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Field, { children: [
818
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(FieldLabel, { children: [
819
+ "Email Address ",
820
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-destructive", children: "*" })
821
+ ] }),
822
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
823
+ Input,
824
+ {
825
+ type: "email",
826
+ value: email,
827
+ onChange: (e) => {
828
+ setEmail(e.target.value);
829
+ clearError("email");
830
+ },
831
+ placeholder: "jane@example.com",
832
+ disabled: isSubmitting,
833
+ "aria-invalid": !!errors.email || void 0
834
+ }
835
+ ),
836
+ errors.email && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FieldError, { children: errors.email })
837
+ ] }),
838
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
839
+ Button,
840
+ {
841
+ type: "submit",
842
+ variant: "default",
843
+ className: "mt-1 w-full",
844
+ disabled: isSubmitting,
845
+ loading: isSubmitting,
846
+ children: [
847
+ "Start Chat",
848
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.ArrowRight, { className: "size-4" })
849
+ ]
850
+ }
851
+ )
852
+ ] }),
853
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { className: "flex items-center justify-center gap-1 text-center text-[11px] text-muted-foreground", children: [
854
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Lock, { className: "size-3" }),
855
+ "Your info is safe with us"
856
+ ] })
857
+ ] });
858
+ }
859
+ function ChatWidgetTopicCard({
860
+ topic,
861
+ onClick,
862
+ className
863
+ }) {
864
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
865
+ Button,
866
+ {
867
+ variant: "outline",
868
+ onClick: () => onClick(topic.id),
869
+ className: cn(
870
+ "h-auto w-full flex-col items-start gap-1.5 whitespace-normal border-border px-3 py-3 text-left",
871
+ "hover:border-primary hover:bg-primary/5",
872
+ className
873
+ ),
874
+ children: [
875
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-muted-foreground", "aria-hidden": "true", children: topic.icon }),
876
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-body-medium font-semibold text-foreground", children: topic.label }),
877
+ topic.description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-body-small leading-snug text-muted-foreground", children: topic.description })
878
+ ]
879
+ }
880
+ );
881
+ }
882
+ function ChatWidgetTopicGrid({
883
+ userName,
884
+ topics = DEFAULT_CHAT_WIDGET_TOPICS,
885
+ onTopicSelect,
886
+ className
887
+ }) {
888
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: cn("flex flex-col gap-4 p-5", className), children: [
889
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
890
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { className: "text-body-large font-semibold text-foreground", children: [
891
+ "Hi ",
892
+ userName,
893
+ "!"
894
+ ] }),
895
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "mt-0.5 text-body-medium text-muted-foreground", children: "What would you like to discuss today?" })
896
+ ] }),
897
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "grid grid-cols-2 gap-2", children: topics.map((topic) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
898
+ ChatWidgetTopicCard,
899
+ {
900
+ topic,
901
+ onClick: onTopicSelect
902
+ },
903
+ topic.id
904
+ )) })
905
+ ] });
906
+ }
907
+ var MEETING_TYPE_LABELS = {
908
+ video: "Video Call",
909
+ phone: "Phone Call",
910
+ "in-person": "In-Person Meeting"
911
+ };
912
+ function MeetingTypeIcon({
913
+ id,
914
+ className = "size-4"
915
+ }) {
916
+ const Icon = id === "video" ? import_lucide_react3.Video : id === "phone" ? import_lucide_react3.Phone : import_lucide_react3.MapPin;
917
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { className: cn("shrink-0 text-muted-foreground", className) });
918
+ }
919
+ function ChatWidgetInteractiveCard({
920
+ type,
921
+ options,
922
+ onQuickReply,
923
+ slots,
924
+ onSlotSelect,
925
+ meetingTypes,
926
+ onMeetingTypeSelect,
927
+ confirmedSlot,
928
+ meetingType,
929
+ topic,
930
+ advisorName,
931
+ className
932
+ }) {
933
+ if (type === "quick-reply") {
934
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cn("flex flex-wrap gap-2 pt-1", className), children: options == null ? void 0 : options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
935
+ Button,
936
+ {
937
+ variant: "outline-primary",
938
+ size: "sm",
939
+ onClick: () => onQuickReply == null ? void 0 : onQuickReply(opt.id),
940
+ children: opt.label
941
+ },
942
+ opt.id
943
+ )) });
944
+ }
945
+ if (type === "appointment") {
946
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
947
+ "div",
948
+ {
949
+ className: cn(
950
+ "flex flex-col gap-2 border border-border bg-card p-3",
951
+ className
952
+ ),
953
+ children: [
954
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-body-small font-semibold text-foreground", children: "Choose a time" }),
955
+ slots == null ? void 0 : slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
956
+ Button,
957
+ {
958
+ variant: "outline",
959
+ onClick: () => onSlotSelect == null ? void 0 : onSlotSelect(slot.id),
960
+ className: "h-auto w-full justify-start gap-2 px-3 py-2 hover:border-primary hover:bg-primary/5",
961
+ children: [
962
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Calendar, { className: "size-4 shrink-0 text-muted-foreground" }),
963
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-foreground", children: slot.datetime })
964
+ ]
965
+ },
966
+ slot.id
967
+ ))
968
+ ]
969
+ }
970
+ );
971
+ }
972
+ if (type === "meeting-type") {
973
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
974
+ "div",
975
+ {
976
+ className: cn(
977
+ "flex flex-col gap-2 border border-border bg-card p-3",
978
+ className
979
+ ),
980
+ children: [
981
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-body-small font-semibold text-foreground", children: "How would you prefer to meet?" }),
982
+ meetingTypes == null ? void 0 : meetingTypes.map((mt) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
983
+ Button,
984
+ {
985
+ variant: "outline",
986
+ onClick: () => onMeetingTypeSelect == null ? void 0 : onMeetingTypeSelect(mt.id),
987
+ className: "h-auto w-full justify-start gap-2 px-3 py-2 hover:border-primary hover:bg-primary/5",
988
+ children: [
989
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MeetingTypeIcon, { id: mt.id }),
990
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-foreground", children: mt.label })
991
+ ]
992
+ },
993
+ mt.id
994
+ ))
995
+ ]
996
+ }
997
+ );
998
+ }
999
+ if (type === "confirmation") {
1000
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1001
+ "div",
1002
+ {
1003
+ className: cn(
1004
+ "flex flex-col gap-3 border border-border bg-card p-3",
1005
+ className
1006
+ ),
1007
+ children: [
1008
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", children: [
1009
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.CheckCircle2, { className: "size-4 shrink-0 text-green-600" }),
1010
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-body-medium font-semibold text-foreground", children: "Appointment Confirmed" })
1011
+ ] }),
1012
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-1.5 border-t border-border pt-2 text-body-small text-muted-foreground", children: [
1013
+ confirmedSlot && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", children: [
1014
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Calendar, { className: "size-3.5 shrink-0" }),
1015
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: confirmedSlot.datetime })
1016
+ ] }),
1017
+ meetingType && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", children: [
1018
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MeetingTypeIcon, { id: meetingType, className: "size-3.5" }),
1019
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: MEETING_TYPE_LABELS[meetingType] })
1020
+ ] }),
1021
+ topic && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", children: [
1022
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.MessageSquare, { className: "size-3.5 shrink-0" }),
1023
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: topic })
1024
+ ] }),
1025
+ advisorName && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", children: [
1026
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.User, { className: "size-3.5 shrink-0" }),
1027
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
1028
+ "with ",
1029
+ advisorName
1030
+ ] })
1031
+ ] })
1032
+ ] })
1033
+ ]
1034
+ }
1035
+ );
1036
+ }
1037
+ return null;
1038
+ }
1039
+ function ChatWidgetWindow({
1040
+ isOpen,
1041
+ brokerName = "Your Broker",
1042
+ brandColor,
1043
+ gradientFrom,
1044
+ gradientTo,
1045
+ onMinimize,
1046
+ onIntakeSubmit,
1047
+ isSubmittingIntake,
1048
+ topics,
1049
+ onTopicSelect,
1050
+ bookingUrl,
1051
+ messages = [],
1052
+ inputValue = "",
1053
+ onInputChange,
1054
+ onSend,
1055
+ isStreaming,
1056
+ onSlotSelect,
1057
+ onQuickReply,
1058
+ onMeetingTypeSelect,
1059
+ initialScreen,
1060
+ initialUser,
1061
+ className
1062
+ }) {
1063
+ var _a;
1064
+ const [screen, setScreen] = (0, import_react3.useState)(
1065
+ () => initialScreen != null ? initialScreen : "topics"
1066
+ );
1067
+ const [user, setUser] = (0, import_react3.useState)(
1068
+ () => initialUser != null ? initialUser : null
1069
+ );
1070
+ const handleIntakeSubmit = (0, import_react3.useCallback)(
1071
+ (data) => {
1072
+ setUser(data);
1073
+ setScreen("topics");
1074
+ onIntakeSubmit == null ? void 0 : onIntakeSubmit(data);
1075
+ },
1076
+ [onIntakeSubmit]
1077
+ );
1078
+ const handleTopicSelect = (0, import_react3.useCallback)(
1079
+ (topicId) => {
1080
+ setScreen(topicId === "book_meeting" && bookingUrl ? "booking" : "chat");
1081
+ onTopicSelect == null ? void 0 : onTopicSelect(topicId);
1082
+ },
1083
+ [onTopicSelect, bookingUrl]
1084
+ );
1085
+ if (!isOpen) return null;
1086
+ const showBackBar = screen === "chat" || screen === "booking";
1087
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1088
+ "div",
1089
+ {
1090
+ className: cn(
1091
+ "flex h-[600px] w-[360px] flex-col overflow-hidden border border-border bg-background shadow-xl",
1092
+ className
1093
+ ),
1094
+ style: brandColor ? { "--primary": brandColor } : void 0,
1095
+ children: [
1096
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1097
+ ChatWidgetHeader,
1098
+ {
1099
+ brokerName,
1100
+ gradientFrom,
1101
+ gradientTo,
1102
+ onMinimize
1103
+ }
1104
+ ),
1105
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex-1 overflow-y-auto", tabIndex: 0, children: [
1106
+ screen === "intake" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1107
+ ChatWidgetIntakeForm,
1108
+ {
1109
+ brokerName,
1110
+ onSubmit: handleIntakeSubmit,
1111
+ isSubmitting: isSubmittingIntake
1112
+ }
1113
+ ),
1114
+ screen === "topics" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1115
+ ChatWidgetTopicGrid,
1116
+ {
1117
+ userName: (_a = user == null ? void 0 : user.name) != null ? _a : "there",
1118
+ topics,
1119
+ onTopicSelect: handleTopicSelect
1120
+ }
1121
+ ),
1122
+ screen === "chat" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex flex-col gap-3 p-4", children: messages.map((msg) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react3.default.Fragment, { children: [
1123
+ (msg.content || msg.isStreaming) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1124
+ ChatWidgetMessage,
1125
+ {
1126
+ role: msg.role,
1127
+ content: msg.content,
1128
+ timestamp: msg.timestamp,
1129
+ isStreaming: msg.isStreaming
1130
+ }
1131
+ ),
1132
+ msg.interactiveCard && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1133
+ ChatWidgetInteractiveCard,
1134
+ __spreadProps(__spreadValues({}, msg.interactiveCard), {
1135
+ onSlotSelect,
1136
+ onQuickReply,
1137
+ onMeetingTypeSelect
1138
+ })
1139
+ )
1140
+ ] }, msg.id)) }),
1141
+ screen === "booking" && bookingUrl && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col items-center gap-5 px-6 py-10 text-center", children: [
1142
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex size-14 items-center justify-center bg-primary/10", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.CalendarDays, { className: "size-7 text-foreground" }) }),
1143
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-1", children: [
1144
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-body-large font-semibold text-foreground", children: "Book an Appointment" }),
1145
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-body-medium text-muted-foreground", children: "Choose a time that works for you with one of our advisors." })
1146
+ ] }),
1147
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1148
+ Button,
1149
+ {
1150
+ variant: "default",
1151
+ className: "w-full",
1152
+ onClick: () => window.open(bookingUrl, "_blank"),
1153
+ children: [
1154
+ "Open Booking Page",
1155
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.ExternalLink, { className: "size-4" })
1156
+ ]
1157
+ }
1158
+ )
1159
+ ] })
1160
+ ] }),
1161
+ showBackBar && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "border-t border-border px-4 py-1.5 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Button, { variant: "ghost", size: "sm", onClick: () => setScreen("topics"), children: [
1162
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.ArrowLeft, { className: "size-3" }),
1163
+ "Change topic"
1164
+ ] }) }),
1165
+ screen === "chat" && onInputChange && onSend && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1166
+ ChatWidgetInputBar,
1167
+ {
1168
+ value: inputValue,
1169
+ onChange: onInputChange,
1170
+ onSend,
1171
+ disabled: isStreaming
1172
+ }
1173
+ )
1174
+ ]
1175
+ }
1176
+ );
1177
+ }
1178
+ function ChatWidget({
1179
+ brokerName = "Your Broker",
1180
+ brandColor,
1181
+ gradientFrom,
1182
+ gradientTo,
1183
+ bookingUrl,
1184
+ position = "bottom-right",
1185
+ defaultOpen = false,
1186
+ onTopicSelected,
1187
+ onMessageSent
1188
+ }) {
1189
+ const [isOpen, setIsOpen] = (0, import_react3.useState)(defaultOpen);
1190
+ const [messages, setMessages] = (0, import_react3.useState)([]);
1191
+ const [inputValue, setInputValue] = (0, import_react3.useState)("");
1192
+ const handleTopicSelect = (0, import_react3.useCallback)(
1193
+ (topicId) => {
1194
+ if (topicId !== "book_meeting" || !bookingUrl) {
1195
+ const topic = DEFAULT_CHAT_WIDGET_TOPICS.find((t) => t.id === topicId);
1196
+ if (topic) {
1197
+ setMessages([
1198
+ {
1199
+ id: "welcome",
1200
+ role: "bot",
1201
+ content: `Great choice! I can help you with ${topic.label.toLowerCase()}. What would you like to know?`
1202
+ }
1203
+ ]);
1204
+ }
1205
+ }
1206
+ onTopicSelected == null ? void 0 : onTopicSelected(topicId);
1207
+ },
1208
+ [onTopicSelected, bookingUrl]
1209
+ );
1210
+ const handleSend = (0, import_react3.useCallback)(
1211
+ (value) => {
1212
+ if (!value.trim()) return;
1213
+ setMessages((prev) => [
1214
+ ...prev,
1215
+ { id: `msg-${Date.now()}`, role: "user", content: value }
1216
+ ]);
1217
+ setInputValue("");
1218
+ onMessageSent == null ? void 0 : onMessageSent(value);
1219
+ },
1220
+ [onMessageSent]
1221
+ );
1222
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1223
+ "div",
1224
+ {
1225
+ className: cn(
1226
+ "fixed bottom-6 z-50 flex flex-col items-end gap-3",
1227
+ position === "bottom-right" ? "right-6" : "left-6"
1228
+ ),
1229
+ children: [
1230
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1231
+ ChatWidgetWindow,
1232
+ {
1233
+ isOpen,
1234
+ brokerName,
1235
+ brandColor,
1236
+ gradientFrom,
1237
+ gradientTo,
1238
+ bookingUrl,
1239
+ onMinimize: () => setIsOpen(false),
1240
+ messages,
1241
+ inputValue,
1242
+ onInputChange: setInputValue,
1243
+ onSend: handleSend,
1244
+ onTopicSelect: handleTopicSelect
1245
+ }
1246
+ ),
1247
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1248
+ ChatWidgetLauncher,
1249
+ {
1250
+ isOpen,
1251
+ onClick: () => setIsOpen((prev) => !prev),
1252
+ brandColor
1253
+ }
1254
+ )
1255
+ ]
1256
+ }
1257
+ );
1258
+ }
1259
+ // Annotate the CommonJS export names for ESM import in node:
1260
+ 0 && (module.exports = {
1261
+ ChatWidget,
1262
+ ChatWidgetIntakeForm,
1263
+ ChatWidgetInteractiveCard,
1264
+ ChatWidgetTopicCard,
1265
+ ChatWidgetTopicGrid,
1266
+ ChatWidgetWindow,
1267
+ DEFAULT_CHAT_WIDGET_TOPICS
1268
+ });