xertica-ui 2.1.2 → 2.1.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 (402) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +1 -1
  3. package/assets/xertica-logo.svg +37 -37
  4. package/assets/xertica-x-logo.svg +20 -20
  5. package/bin/cli.ts +1 -1
  6. package/bin/generate-tokens.ts +13 -7
  7. package/components/assistant/index.ts +6 -6
  8. package/components/assistant/xertica-assistant/index.ts +2 -0
  9. package/components/assistant/xertica-assistant/use-assistant.ts +564 -0
  10. package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +200 -0
  11. package/components/assistant/xertica-assistant/xertica-assistant.tsx +183 -474
  12. package/components/blocks/card-patterns/ActivityCard.tsx +72 -72
  13. package/components/blocks/card-patterns/FeatureCard.tsx +100 -100
  14. package/components/blocks/card-patterns/NotificationCard.tsx +127 -127
  15. package/components/blocks/card-patterns/ProfileCard.tsx +84 -84
  16. package/components/blocks/card-patterns/ProjectCard.tsx +89 -89
  17. package/components/blocks/card-patterns/QuickActionCard.tsx +62 -62
  18. package/components/blocks/card-patterns/card-patterns.stories.tsx +445 -445
  19. package/components/blocks/card-patterns/index.ts +17 -17
  20. package/components/blocks/index.ts +1 -1
  21. package/components/brand/index.ts +6 -6
  22. package/components/brand/xertica-provider/XerticaProvider.tsx +48 -48
  23. package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
  24. package/components/brand/xertica-provider/xertica-provider.test.tsx +52 -52
  25. package/components/examples/MapExamples.tsx +282 -282
  26. package/components/examples/SimpleFilterableMap.tsx +191 -191
  27. package/components/examples/index.ts +51 -51
  28. package/components/figma/ImageWithFallback.tsx +27 -27
  29. package/components/hooks/index.ts +7 -7
  30. package/components/index.ts +5 -5
  31. package/components/layout/header/header.test.tsx +8 -8
  32. package/components/layout/header/header.tsx +4 -4
  33. package/components/layout/index.ts +2 -2
  34. package/components/layout/sidebar/index.ts +2 -0
  35. package/components/layout/sidebar/sidebar.mdx +1 -1
  36. package/components/layout/sidebar/sidebar.stories.tsx +160 -8
  37. package/components/layout/sidebar/sidebar.test.tsx +11 -11
  38. package/components/layout/sidebar/sidebar.tsx +610 -471
  39. package/components/layout/sidebar/use-sidebar.ts +113 -0
  40. package/components/media/FloatingMediaWrapper.tsx +11 -11
  41. package/components/media/audio-player/AudioPlayer.tsx +22 -22
  42. package/components/media/index.ts +3 -3
  43. package/components/pages/home-content/HomeContent.tsx +7 -7
  44. package/components/pages/home-content/home-content.mdx +62 -62
  45. package/components/pages/home-page/HomePage.stories.tsx +39 -39
  46. package/components/pages/home-page/HomePage.tsx +1 -1
  47. package/components/pages/home-page/home-page.mdx +53 -53
  48. package/components/pages/index.ts +8 -8
  49. package/components/pages/template-content/TemplateContent.tsx +5 -5
  50. package/components/pages/template-content/template-content.mdx +61 -61
  51. package/components/pages/template-page/TemplatePage.stories.tsx +39 -39
  52. package/components/pages/template-page/TemplatePage.tsx +5 -5
  53. package/components/pages/template-page/template-page.mdx +53 -53
  54. package/components/public-api-smoke.test.tsx +52 -52
  55. package/components/shared/assistant-utils.ts +43 -43
  56. package/components/shared/layout-constants.ts +1 -1
  57. package/components/ui/accordion/accordion.mdx +8 -8
  58. package/components/ui/accordion/accordion.stories.tsx +53 -53
  59. package/components/ui/alert/alert.mdx +8 -8
  60. package/components/ui/alert-dialog/alert-dialog.mdx +8 -8
  61. package/components/ui/aspect-ratio/aspect-ratio.mdx +8 -8
  62. package/components/ui/assistant-chart/assistant-chart.mdx +8 -8
  63. package/components/ui/avatar/avatar.mdx +8 -8
  64. package/components/ui/badge/badge.mdx +8 -8
  65. package/components/ui/badge/badge.tsx +9 -9
  66. package/components/ui/breadcrumb/breadcrumb.mdx +8 -8
  67. package/components/ui/button/button.mdx +8 -8
  68. package/components/ui/calendar/calendar.mdx +8 -8
  69. package/components/ui/calendar/calendar.tsx +258 -258
  70. package/components/ui/card/card.mdx +8 -8
  71. package/components/ui/card/card.stories.tsx +245 -245
  72. package/components/ui/carousel/carousel.mdx +8 -8
  73. package/components/ui/chart/chart.mdx +8 -8
  74. package/components/ui/chart/chart.stories.tsx +1303 -344
  75. package/components/ui/chart/chart.test.tsx +154 -154
  76. package/components/ui/chart/chart.tsx +2367 -1494
  77. package/components/ui/checkbox/checkbox.mdx +8 -8
  78. package/components/ui/checkbox/checkbox.stories.tsx +20 -20
  79. package/components/ui/collapsible/collapsible.mdx +8 -8
  80. package/components/ui/command/command.mdx +8 -8
  81. package/components/ui/context-menu/context-menu.mdx +8 -8
  82. package/components/ui/dialog/dialog.mdx +8 -8
  83. package/components/ui/drawer/drawer.mdx +8 -8
  84. package/components/ui/dropdown-menu/dropdown-menu.mdx +8 -8
  85. package/components/ui/empty/empty.mdx +8 -8
  86. package/components/ui/file-upload/file-upload.mdx +8 -8
  87. package/components/ui/file-upload/file-upload.stories.tsx +100 -0
  88. package/components/ui/file-upload/file-upload.tsx +14 -74
  89. package/components/ui/file-upload/index.ts +1 -0
  90. package/components/ui/file-upload/use-file-upload.ts +181 -0
  91. package/components/ui/google-maps-loader/google-maps-loader.tsx +2 -2
  92. package/components/ui/hover-card/hover-card.mdx +8 -8
  93. package/components/ui/input/input.mdx +8 -8
  94. package/components/ui/input-otp/input-otp.mdx +8 -8
  95. package/components/ui/input-otp/input-otp.stories.tsx +6 -6
  96. package/components/ui/label/label.mdx +8 -8
  97. package/components/ui/map/map.mdx +8 -8
  98. package/components/ui/map/map.stories.tsx +51 -51
  99. package/components/ui/map/map.tsx +2 -2
  100. package/components/ui/menubar/menubar.mdx +8 -8
  101. package/components/ui/navigation-menu/navigation-menu.mdx +8 -8
  102. package/components/ui/notification-badge/notification-badge.mdx +8 -8
  103. package/components/ui/pagination/index.ts +2 -0
  104. package/components/ui/pagination/pagination.mdx +8 -8
  105. package/components/ui/pagination/pagination.stories.tsx +94 -0
  106. package/components/ui/pagination/use-pagination.ts +194 -0
  107. package/components/ui/popover/popover.mdx +8 -8
  108. package/components/ui/progress/progress.mdx +8 -8
  109. package/components/ui/progress/progress.tsx +68 -68
  110. package/components/ui/radio-group/radio-group.mdx +8 -8
  111. package/components/ui/rating/rating.mdx +8 -8
  112. package/components/ui/resizable/resizable.mdx +8 -8
  113. package/components/ui/rich-text-editor/index.ts +2 -0
  114. package/components/ui/rich-text-editor/rich-text-editor.stories.tsx +129 -1
  115. package/components/ui/rich-text-editor/rich-text-editor.tsx +86 -305
  116. package/components/ui/rich-text-editor/use-rich-text-editor.ts +439 -0
  117. package/components/ui/route-map/route-map.mdx +8 -8
  118. package/components/ui/route-map/route-map.stories.tsx +54 -54
  119. package/components/ui/route-map/route-map.tsx +2 -2
  120. package/components/ui/scroll-area/scroll-area.mdx +8 -8
  121. package/components/ui/search/search.mdx +8 -8
  122. package/components/ui/select/select.mdx +8 -8
  123. package/components/ui/select/select.stories.tsx +9 -9
  124. package/components/ui/separator/separator.mdx +8 -8
  125. package/components/ui/sheet/sheet.mdx +8 -8
  126. package/components/ui/sheet/sheet.stories.tsx +95 -95
  127. package/components/ui/simple-map/simple-map.mdx +8 -8
  128. package/components/ui/simple-map/simple-map.stories.tsx +48 -48
  129. package/components/ui/skeleton/skeleton.mdx +8 -8
  130. package/components/ui/slider/slider.mdx +8 -8
  131. package/components/ui/sonner/sonner.mdx +8 -8
  132. package/components/ui/stats-card/stats-card.mdx +8 -8
  133. package/components/ui/stepper/index.ts +3 -1
  134. package/components/ui/stepper/stepper.mdx +8 -8
  135. package/components/ui/stepper/stepper.stories.tsx +116 -0
  136. package/components/ui/stepper/stepper.tsx +4 -4
  137. package/components/ui/stepper/use-stepper.ts +137 -0
  138. package/components/ui/switch/switch.mdx +8 -8
  139. package/components/ui/switch/switch.stories.tsx +20 -20
  140. package/components/ui/table/table.mdx +8 -8
  141. package/components/ui/tabs/tabs.mdx +8 -8
  142. package/components/ui/tabs/tabs.stories.tsx +26 -26
  143. package/components/ui/textarea/textarea.mdx +8 -8
  144. package/components/ui/timeline/timeline.mdx +8 -8
  145. package/components/ui/toggle/toggle.mdx +8 -8
  146. package/components/ui/toggle-group/toggle-group.mdx +8 -8
  147. package/components/ui/tooltip/tooltip.mdx +8 -8
  148. package/components/ui/tree-view/index.ts +4 -1
  149. package/components/ui/tree-view/tree-view.mdx +8 -8
  150. package/components/ui/tree-view/tree-view.stories.tsx +110 -4
  151. package/components/ui/tree-view/tree-view.tsx +17 -125
  152. package/components/ui/tree-view/use-tree-view.ts +229 -0
  153. package/components.json +1512 -1512
  154. package/contexts/ApiKeyContext.tsx +72 -72
  155. package/contexts/BrandColorsContext.tsx +26 -26
  156. package/contexts/LanguageContext.tsx +13 -13
  157. package/contexts/LayoutContext.test.tsx +11 -11
  158. package/contexts/LayoutContext.tsx +29 -29
  159. package/contexts/ThemeContext.tsx +26 -26
  160. package/contexts/theme-data.ts +4 -4
  161. package/dist/{AssistantChart-CVzmmhx4.js → AssistantChart-C_hwFRRr.js} +4 -4
  162. package/dist/{AssistantChart-BAx9VQvb.cjs → AssistantChart-CldVCVDe.cjs} +311 -94
  163. package/dist/{AssistantChart-CVko2A1W.js → AssistantChart-Cu3m7RBo.js} +314 -97
  164. package/dist/{AssistantChart-9w31gdAb.cjs → AssistantChart-DoZCyS5r.cjs} +4 -4
  165. package/dist/AudioPlayer-B1lt5cPl.cjs +989 -0
  166. package/dist/AudioPlayer-BZ7bibzU.cjs +982 -0
  167. package/dist/AudioPlayer-C12BjQBV.cjs +997 -0
  168. package/dist/AudioPlayer-DMcG_c7L.js +990 -0
  169. package/dist/AudioPlayer-DcFKRJE_.js +998 -0
  170. package/dist/AudioPlayer-e8LfNoqO.js +983 -0
  171. package/dist/{xertica-assistant-Qp3ydksa.cjs → CodeBlock-7TTgmdGG.cjs} +263 -51
  172. package/dist/{xertica-assistant-gnCJdcZY.js → CodeBlock-BeSt1h5P.js} +219 -7
  173. package/dist/CodeBlock-BgfYL_rD.cjs +2094 -0
  174. package/dist/CodeBlock-BlcqlA9M.cjs +2094 -0
  175. package/dist/CodeBlock-Bnmeu5ez.cjs +2094 -0
  176. package/dist/CodeBlock-BtfPlbAI.js +2078 -0
  177. package/dist/CodeBlock-CIySIuYr.js +2078 -0
  178. package/dist/CodeBlock-CuPtUM-7.cjs +2094 -0
  179. package/dist/CodeBlock-D6ffWXgc.js +2078 -0
  180. package/dist/CodeBlock-D8dcwbit.cjs +2094 -0
  181. package/dist/CodeBlock-DMZrFnlw.cjs +2094 -0
  182. package/dist/CodeBlock-DlBehYN8.js +2078 -0
  183. package/dist/CodeBlock-DnYNI8rQ.js +2078 -0
  184. package/dist/CodeBlock-DvKWbSnE.cjs +2094 -0
  185. package/dist/CodeBlock-DwMCfkFY.js +2078 -0
  186. package/dist/CodeBlock-Dy6CNYyj.js +2078 -0
  187. package/dist/CodeBlock-U1pPOQI7.cjs +2094 -0
  188. package/dist/CodeBlock-f_GpNhEB.js +2078 -0
  189. package/dist/CodeBlock-oB6u8nI1.js +2078 -0
  190. package/dist/CodeBlock-tZC31B73.cjs +2094 -0
  191. package/dist/ImageWithFallback-CGtidP6B.cjs +4542 -0
  192. package/dist/ImageWithFallback-lsg3pdFg.js +4508 -0
  193. package/dist/LanguageSelector-B5YfbHra.js +231 -0
  194. package/dist/LanguageSelector-D6uacAIM.cjs +230 -0
  195. package/dist/LayoutContext-BAql6ZRY.js +97 -0
  196. package/dist/LayoutContext-BvK-ggDa.cjs +96 -0
  197. package/dist/ThemeContext-BoH4NLfN.js +734 -0
  198. package/dist/{ThemeContext-BbBNoFTG.js → ThemeContext-C2EwAPDt.js} +2 -2
  199. package/dist/ThemeContext-r69W20Xg.cjs +733 -0
  200. package/dist/{ThemeContext-Cmr8Ex8H.cjs → ThemeContext-vTjumZeM.cjs} +2 -2
  201. package/dist/{VerifyEmailPage-BE-L9mB7.js → VerifyEmailPage-C0c2e5n0.js} +7 -7
  202. package/dist/{VerifyEmailPage-DMBh4NM9.cjs → VerifyEmailPage-CYXtbKi3.cjs} +1 -1
  203. package/dist/{VerifyEmailPage-CR7kb5df.cjs → VerifyEmailPage-Cwi3kbol.cjs} +7 -7
  204. package/dist/{VerifyEmailPage-CdYPSJoO.js → VerifyEmailPage-DvMLZgFt.js} +1 -1
  205. package/dist/XerticaOrbe-KL1RBHzw.cjs +1354 -0
  206. package/dist/XerticaOrbe-zwS1p2a8.js +1355 -0
  207. package/dist/XerticaProvider-6btlAlzc.js +17 -0
  208. package/dist/XerticaProvider-BNoNOxQ5.cjs +16 -0
  209. package/dist/XerticaProvider-BlY2limY.cjs +38 -0
  210. package/dist/{XerticaProvider-BITjgC5p.js → XerticaProvider-CEoWMTxu.js} +2 -2
  211. package/dist/{XerticaProvider-By8q3Roe.cjs → XerticaProvider-CllrbMEJ.cjs} +2 -2
  212. package/dist/XerticaProvider-DDuiIcKo.js +39 -0
  213. package/dist/XerticaProvider-cI9hSs27.cjs +38 -0
  214. package/dist/XerticaProvider-hSwhNQex.js +39 -0
  215. package/dist/{alert-dialog-yckpaOpy.cjs → alert-dialog-DSKByiKZ.cjs} +3 -3
  216. package/dist/{alert-dialog-iDe5VE5o.js → alert-dialog-s-vmNkJ_.js} +3 -3
  217. package/dist/assistant.cjs.js +2 -1
  218. package/dist/assistant.es.js +3 -2
  219. package/dist/brand.cjs.js +1 -1
  220. package/dist/brand.es.js +1 -1
  221. package/dist/breadcrumb-CqJ7bHY5.js +161 -0
  222. package/dist/breadcrumb-m9Hb2_XN.cjs +177 -0
  223. package/dist/cli.js +14 -8
  224. package/dist/components/assistant/xertica-assistant/index.d.ts +2 -0
  225. package/dist/components/assistant/xertica-assistant/use-assistant.d.ts +126 -0
  226. package/dist/components/assistant/xertica-assistant/xertica-assistant.d.ts +7 -2
  227. package/dist/components/blocks/audio-player/AudioPlayer.d.ts +35 -0
  228. package/dist/components/blocks/audio-player/index.d.ts +1 -0
  229. package/dist/components/blocks/document-editor/DocumentEditor.d.ts +26 -0
  230. package/dist/components/blocks/document-editor/index.d.ts +1 -0
  231. package/dist/components/blocks/podcast-player/PodcastPlayer.d.ts +41 -0
  232. package/dist/components/blocks/podcast-player/index.d.ts +1 -0
  233. package/dist/components/layout/sidebar/index.d.ts +2 -0
  234. package/dist/components/layout/sidebar/sidebar.d.ts +80 -0
  235. package/dist/components/layout/sidebar/use-sidebar.d.ts +22 -0
  236. package/dist/components/shared/layout-constants.d.ts +1 -1
  237. package/dist/components/ui/button/button.d.ts +1 -1
  238. package/dist/components/ui/chart/chart.d.ts +162 -5
  239. package/dist/components/ui/file-upload/file-upload.d.ts +2 -0
  240. package/dist/components/ui/file-upload/index.d.ts +1 -0
  241. package/dist/components/ui/file-upload/use-file-upload.d.ts +49 -0
  242. package/dist/components/ui/pagination/index.d.ts +2 -0
  243. package/dist/components/ui/pagination/use-pagination.d.ts +78 -0
  244. package/dist/components/ui/rich-text-editor/index.d.ts +2 -0
  245. package/dist/components/ui/rich-text-editor/use-rich-text-editor.d.ts +107 -0
  246. package/dist/components/ui/stepper/index.d.ts +3 -1
  247. package/dist/components/ui/stepper/stepper.d.ts +2 -2
  248. package/dist/components/ui/stepper/use-stepper.d.ts +60 -0
  249. package/dist/components/ui/tree-view/index.d.ts +4 -1
  250. package/dist/components/ui/tree-view/tree-view.d.ts +4 -6
  251. package/dist/components/ui/tree-view/use-tree-view.d.ts +60 -0
  252. package/dist/dropdown-menu-BDB5CmQs.cjs +247 -0
  253. package/dist/dropdown-menu-DQidbKBD.js +231 -0
  254. package/dist/google-maps-loader-BFWp6VPd.js +287 -0
  255. package/dist/{google-maps-loader-t2IlYBzw.js → google-maps-loader-CTYySAun.js} +4 -0
  256. package/dist/{google-maps-loader-BqsYL48U.cjs → google-maps-loader-Y-QkD-Li.cjs} +5 -0
  257. package/dist/google-maps-loader-eS3uQ5TA.cjs +287 -0
  258. package/dist/header-Cgy6vYPk.cjs +731 -0
  259. package/dist/header-DRlT4jgI.js +715 -0
  260. package/dist/header-Dux00SI4.cjs +731 -0
  261. package/dist/header-EkGKXPsD.js +715 -0
  262. package/dist/header-WfEywpyc.cjs +731 -0
  263. package/dist/header-tifNQn2U.js +715 -0
  264. package/dist/hooks.cjs.js +1 -1
  265. package/dist/hooks.es.js +1 -1
  266. package/dist/index-BhapVLVj.js +8 -0
  267. package/dist/{index-D3RLKRAs.cjs → index-COtD8bRW.cjs} +1 -1
  268. package/dist/index-D6fxYEY8.cjs +7 -0
  269. package/dist/index-DW5tYe26.js +8 -0
  270. package/dist/index.cjs.js +19 -8
  271. package/dist/index.es.js +39 -28
  272. package/dist/index.umd.js +1043 -470
  273. package/dist/input-2R4loU86.js +127 -0
  274. package/dist/input-DWANSKGb.cjs +145 -0
  275. package/dist/layout.cjs.js +89 -1
  276. package/dist/layout.es.js +90 -2
  277. package/dist/pages.cjs.js +1 -1
  278. package/dist/pages.es.js +1 -1
  279. package/dist/rich-text-editor-0mraWT5y.cjs +2376 -0
  280. package/dist/rich-text-editor-B6jMRLzk.cjs +1939 -0
  281. package/dist/rich-text-editor-B8_oYcIR.js +1730 -0
  282. package/dist/rich-text-editor-B9UbSXNb.js +1203 -0
  283. package/dist/rich-text-editor-BYuRBNBU.js +2373 -0
  284. package/dist/rich-text-editor-Bb9pySTs.cjs +2374 -0
  285. package/dist/rich-text-editor-BcL6L3cm.cjs +2374 -0
  286. package/dist/rich-text-editor-BoVZYtTs.cjs +2391 -0
  287. package/dist/rich-text-editor-CPV1lEPH.cjs +1748 -0
  288. package/dist/rich-text-editor-CoKqbCtu.cjs +1799 -0
  289. package/dist/rich-text-editor-Cw56T_mB.js +2356 -0
  290. package/dist/rich-text-editor-Cyt8qs2b.js +1921 -0
  291. package/dist/rich-text-editor-D6H84OcX.cjs +1220 -0
  292. package/dist/rich-text-editor-D76gD-QI.js +2328 -0
  293. package/dist/rich-text-editor-DKkokOnA.js +1781 -0
  294. package/dist/rich-text-editor-DNsdpN64.cjs +2359 -0
  295. package/dist/rich-text-editor-DfG8bCyY.js +2358 -0
  296. package/dist/rich-text-editor-DgF8s7xW.js +2949 -0
  297. package/dist/rich-text-editor-Dxjw31Z4.js +2341 -0
  298. package/dist/rich-text-editor-DzP0Epmb.js +2356 -0
  299. package/dist/rich-text-editor-mWoaSCE4.cjs +2966 -0
  300. package/dist/rich-text-editor-skplNlBM.cjs +2345 -0
  301. package/dist/select-Bkbr0f-Z.cjs +162 -0
  302. package/dist/select-CvIVdX2n.js +145 -0
  303. package/dist/sidebar-CK_0ZQHj.cjs +803 -0
  304. package/dist/sidebar-CUuOvYhK.js +787 -0
  305. package/dist/slider-Bc5Hd0y1.js +56 -0
  306. package/dist/slider-N7hFFj6X.cjs +73 -0
  307. package/dist/tooltip-Ded96neP.cjs +137 -0
  308. package/dist/tooltip-HDOoD2-0.js +120 -0
  309. package/dist/ui.cjs.js +14 -4
  310. package/dist/ui.es.js +26 -16
  311. package/dist/use-mobile-B0hNy_Y6.cjs +4303 -0
  312. package/dist/use-mobile-BXuYROXM.js +4202 -0
  313. package/dist/use-mobile-Bbd51ASU.cjs +4392 -0
  314. package/dist/use-mobile-Bk6CX-TC.js +4359 -0
  315. package/dist/use-mobile-BvYdisLP.js +4202 -0
  316. package/dist/use-mobile-BzuxjzNX.cjs +4392 -0
  317. package/dist/use-mobile-CG2-SdXV.cjs +4235 -0
  318. package/dist/use-mobile-CKb5pqTs.js +4269 -0
  319. package/dist/use-mobile-CYuAuGDl.js +4202 -0
  320. package/dist/use-mobile-CaENcqm-.js +4508 -0
  321. package/dist/use-mobile-CbrYgJGJ.js +4203 -0
  322. package/dist/use-mobile-DMOvImGQ.cjs +4542 -0
  323. package/dist/use-mobile-DRB3BQgD.cjs +4235 -0
  324. package/dist/use-mobile-DZvv7QMR.js +4359 -0
  325. package/dist/use-mobile-DdI_TXam.cjs +4235 -0
  326. package/dist/use-mobile-DlceKf8a.js +4359 -0
  327. package/dist/use-mobile-DsOnow1o.cjs +4236 -0
  328. package/dist/use-mobile-Kcj6jSnK.cjs +4392 -0
  329. package/dist/use-mobile-bnKcua_i.js +4202 -0
  330. package/dist/use-mobile-ncXBeE2z.cjs +4235 -0
  331. package/dist/{xertica-assistant-B1IaHXnB.cjs → xertica-assistant-dyP7KHM5.cjs} +533 -392
  332. package/dist/{xertica-assistant-DPsESB6t.js → xertica-assistant-yX1CFBBo.js} +535 -394
  333. package/dist/xertica-ui.css +2 -2
  334. package/docs/ai-usage.md +28 -10
  335. package/docs/architecture.md +76 -0
  336. package/docs/components/assistant.md +159 -0
  337. package/docs/components/calendar.md +154 -154
  338. package/docs/components/card-patterns.md +337 -337
  339. package/docs/components/card.md +235 -235
  340. package/docs/components/chart.md +354 -39
  341. package/docs/components/file-upload.md +119 -2
  342. package/docs/components/map.md +84 -84
  343. package/docs/components/pagination.md +187 -0
  344. package/docs/components/rich-text-editor.md +164 -0
  345. package/docs/components/sidebar.md +153 -4
  346. package/docs/components/stepper.md +157 -12
  347. package/docs/components/tree-view.md +164 -6
  348. package/docs/components/xertica-provider.md +24 -24
  349. package/docs/decision-tree.md +287 -287
  350. package/docs/getting-started.md +1 -1
  351. package/docs/guidelines.md +14 -8
  352. package/docs/layout.md +2 -2
  353. package/docs/llms.md +4 -4
  354. package/guidelines/Guidelines.md +252 -250
  355. package/hooks/useTheme.ts +3 -3
  356. package/imports/Podcast.tsx +388 -388
  357. package/imports/XerticaAi.tsx +45 -45
  358. package/imports/XerticaX.tsx +19 -19
  359. package/imports/svg-aueiaqngck.ts +11 -11
  360. package/imports/svg-v9krss1ozd.ts +16 -16
  361. package/imports/svg-vhrdofe3qe.ts +5 -5
  362. package/llms-compact.txt +327 -327
  363. package/llms.txt +160 -160
  364. package/package.json +203 -203
  365. package/styles/xertica/app-overrides/chat.css +61 -61
  366. package/styles/xertica/app-overrides/scrollbar.css +33 -33
  367. package/styles/xertica/integrations/google-maps.css +76 -76
  368. package/styles/xertica/integrations/sonner.css +73 -73
  369. package/styles/xertica/tokens.css +41 -12
  370. package/templates/CLAUDE.md +182 -172
  371. package/templates/guidelines/Guidelines.md +325 -313
  372. package/templates/package.json +3 -3
  373. package/templates/src/features/auth/index.ts +4 -4
  374. package/templates/src/features/auth/ui/AuthPageShell.tsx +34 -34
  375. package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -70
  376. package/templates/src/features/auth/ui/LoginContent.tsx +90 -90
  377. package/templates/src/features/auth/ui/ResetPasswordContent.tsx +151 -151
  378. package/templates/src/features/auth/ui/SocialLoginButtons.tsx +59 -59
  379. package/templates/src/features/auth/ui/VerifyEmailContent.tsx +82 -82
  380. package/templates/src/features/home/index.ts +1 -1
  381. package/templates/src/features/home/ui/HomeContent.tsx +100 -100
  382. package/templates/src/features/template/index.ts +5 -5
  383. package/templates/src/features/template/ui/CrudTemplate.tsx +3 -3
  384. package/templates/src/features/template/ui/DashboardTemplate.tsx +3 -3
  385. package/templates/src/features/template/ui/FormTemplate.tsx +120 -120
  386. package/templates/src/features/template/ui/LoginTemplate.tsx +3 -3
  387. package/templates/src/pages/AssistantPage.tsx +328 -328
  388. package/templates/src/pages/ForgotPasswordPage.tsx +6 -6
  389. package/templates/src/pages/HomePage.tsx +57 -57
  390. package/templates/src/pages/LoginPage.tsx +10 -10
  391. package/templates/src/pages/ResetPasswordPage.tsx +6 -6
  392. package/templates/src/pages/TemplatePage.tsx +30 -30
  393. package/templates/src/pages/VerifyEmailPage.tsx +6 -6
  394. package/templates/src/shared/config/navigation.ts +20 -20
  395. package/templates/src/shared/lib/auth.ts +20 -20
  396. package/templates/src/shared/types/auth.ts +3 -3
  397. package/templates/src/styles/xertica/tokens.css +39 -10
  398. package/templates/tsconfig.json +5 -5
  399. package/utils/gemini.ts +140 -140
  400. package/dist/VerifyEmailPage-Bae2cBXT.cjs +0 -2827
  401. package/dist/VerifyEmailPage-CbgjOF0v.js +0 -2828
  402. package/dist/index-CkTUgOwX.js +0 -8
@@ -1,328 +1,328 @@
1
- import { useState, useMemo, useEffect } from 'react';
2
- import { useNavigate, Link } from 'react-router-dom';
3
- import { XerticaAssistant, generateDemoResponse } from 'xertica-ui/assistant';
4
- import { useLayout } from 'xertica-ui/hooks';
5
- import { Header } from 'xertica-ui/layout';
6
- import {
7
- Button,
8
- AlertDialog, AlertDialogAction, AlertDialogCancel,
9
- AlertDialogContent, AlertDialogDescription, AlertDialogFooter,
10
- AlertDialogHeader, AlertDialogTitle,
11
- Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle,
12
- Input, Label,
13
- } from 'xertica-ui/ui';
14
- import { AppLayout } from '../app/components/AppLayout';
15
- import { ArrowLeft, Plus, MessageSquare, Trash2, FileEdit } from 'lucide-react';
16
-
17
- // ─── Types ───────────────────────────────────────────────────────────────────
18
-
19
- interface ChatMessage {
20
- id: string;
21
- type: 'user' | 'assistant';
22
- content: string;
23
- timestamp: Date;
24
- }
25
-
26
- interface Conversation {
27
- id: string;
28
- label: string;
29
- group: 'hoje' | 'ontem' | 'semana';
30
- messages: ChatMessage[];
31
- }
32
-
33
- // ─── Data ────────────────────────────────────────────────────────────────────
34
-
35
- const richSuggestions = [
36
- { id: 'chart-1', text: 'Ver análise de performance' },
37
- { id: 'table-1', text: 'Gerar relatório de projetos' },
38
- { id: 'doc-1', text: 'Criar documento de requisitos' },
39
- { id: 'pod-1', text: 'Gerar podcast do resumo diário' },
40
- ];
41
-
42
- const feedbackOptions = [
43
- 'Não era o que eu procurava',
44
- 'Informação incorreta',
45
- 'Resposta incompleta',
46
- ];
47
-
48
- const d = (offsetMinutes: number) => {
49
- const t = new Date();
50
- t.setMinutes(t.getMinutes() - offsetMinutes);
51
- return t;
52
- };
53
-
54
- const INITIAL_CONVERSATIONS: Conversation[] = [
55
- {
56
- id: 'conversa-1',
57
- label: 'Análise de dados de vendas Q1',
58
- group: 'hoje',
59
- messages: [
60
- { id: 'm1', type: 'user', content: 'Preciso de uma análise dos dados de vendas do primeiro trimestre. Tivemos crescimento em algumas regiões mas queda em outras.', timestamp: d(60) },
61
- { id: 'm2', type: 'assistant', content: 'Com base nos dados do Q1, identifiquei os seguintes padrões:\n\n**Regiões com crescimento:**\n- Sudeste: +18% comparado ao Q1 do ano anterior\n- Sul: +12%\n\n**Regiões com queda:**\n- Norte: -8%\n- Nordeste: -4%\n\nO crescimento no Sudeste foi impulsionado principalmente pelo aumento no ticket médio (+22%), enquanto a queda no Norte está correlacionada com a redução de representantes comerciais ativos na região. Recomendo aumentar a cobertura comercial no Norte e Nordeste para o Q2.', timestamp: d(58) },
62
- { id: 'm3', type: 'user', content: 'Que ações específicas você recomenda para o Norte?', timestamp: d(55) },
63
- { id: 'm4', type: 'assistant', content: 'Para reverter a queda no Norte, recomendo:\n\n1. **Contratar 2 representantes regionais** focados nos estados do Pará e Amazonas\n2. **Programa de incentivo para distribuidores locais** com bonificação por volume trimestral\n3. **Campanhas segmentadas** com preços ajustados ao poder aquisitivo regional\n4. **Visitas presenciais quinzenais** nos 5 maiores clientes da região\n\nEssas ações têm potencial de recuperar 6-8% das vendas já no Q2.', timestamp: d(53) },
64
- ],
65
- },
66
- {
67
- id: 'conversa-2',
68
- label: 'Relatório de performance mensal',
69
- group: 'hoje',
70
- messages: [
71
- { id: 'm1', type: 'user', content: 'Gera um relatório de performance do time de engenharia para o mês de abril.', timestamp: d(120) },
72
- { id: 'm2', type: 'assistant', content: '# Relatório de Performance — Abril\n\n**Time de Engenharia**\n\n## Entregas\n- 42 tarefas concluídas (meta: 38) ✅\n- 3 sprints fechados dentro do prazo\n- Velocity médio: 87 pontos/sprint\n\n## Qualidade\n- Taxa de bugs em produção: 0,8% (melhora de 0,3pp vs março)\n- Cobertura de testes: 78%\n- Tempo médio de resolução de incidentes: 2h 15min\n\n## Destaques\n- Deploy do módulo de relatórios avançados (2 semanas antes do prazo)\n- Redução de 40% no tempo de build do pipeline\n\n## Pontos de atenção\n- Dívida técnica no módulo de autenticação precisa de endereçamento no Q2', timestamp: d(118) },
73
- ],
74
- },
75
- {
76
- id: 'conversa-3',
77
- label: 'Resumo das reuniões da semana',
78
- group: 'ontem',
79
- messages: [
80
- { id: 'm1', type: 'user', content: 'Resume as principais decisões tomadas nas reuniões desta semana.', timestamp: d(1440 + 60) },
81
- { id: 'm2', type: 'assistant', content: '## Decisões da Semana\n\n**Segunda — Planejamento Q2**\n- Meta de receita: R$ 4,2M (+15% vs Q1)\n- Novo produto B2B entra em beta em junho\n- Contratação de 3 devs aprovada para maio\n\n**Quarta — Review de Produto**\n- Funcionalidade de relatórios vai para produção na sexta\n- UX do onboarding será redesenhado (kickoff em 15/05)\n- Integração com ERP do cliente Alfa postergada para julho\n\n**Sexta — All Hands**\n- Empresa atingiu 500 clientes ativos 🎉\n- Novo programa de equity para colaboradores aprovado pelo board\n- Hackathon interno marcado para 20-21 de junho', timestamp: d(1440 + 58) },
82
- { id: 'm3', type: 'user', content: 'Quando é o kickoff do redesign de UX exatamente?', timestamp: d(1440 + 50) },
83
- { id: 'm4', type: 'assistant', content: 'O kickoff do redesign do onboarding está marcado para **15 de maio**, conforme decidido na reunião de Review de Produto de quarta-feira. O time de produto e design estará presente, e foi solicitado que o lead de engenharia frontend também participe.', timestamp: d(1440 + 48) },
84
- ],
85
- },
86
- {
87
- id: 'conversa-4',
88
- label: 'Dashboard de projetos ativos',
89
- group: 'ontem',
90
- messages: [
91
- { id: 'm1', type: 'user', content: 'Quais projetos estão ativos agora e qual o status de cada um?', timestamp: d(1440 + 180) },
92
- { id: 'm2', type: 'assistant', content: '## Projetos Ativos\n\n| Projeto | Status | Prazo | Responsável |\n|---|---|---|---|\n| Portal do Cliente | 🟢 No prazo | 30/05 | Ana Costa |\n| Integração ERP | 🟡 Em risco | 15/05 | Bruno Lima |\n| App Mobile v2 | 🟢 No prazo | 30/06 | Carla Melo |\n| Redesign Onboarding | 🔵 Iniciando | 30/07 | Diana Park |\n| API Pública v3 | 🟡 Em risco | 01/06 | Eduardo Cruz |\n\n**Projetos em risco:** A Integração ERP está aguardando credenciais do cliente Alfa há 10 dias. A API v3 tem bloqueio técnico na autenticação OAuth que precisa de decisão arquitetural.', timestamp: d(1440 + 178) },
93
- ],
94
- },
95
- {
96
- id: 'conversa-5',
97
- label: 'Análise de churn de clientes',
98
- group: 'ontem',
99
- messages: [
100
- { id: 'm1', type: 'user', content: 'Analisa o churn do mês passado. Tivemos 12 cancelamentos.', timestamp: d(1440 + 300) },
101
- { id: 'm2', type: 'assistant', content: '## Análise de Churn — Abril\n\n**12 cancelamentos** representam uma taxa de churn de **2,4%** (base de 500 clientes).\n\n### Principais motivos\n1. Preço / custo-benefício — 5 clientes (42%)\n2. Migração para concorrente — 4 clientes (33%)\n3. Encerramento do negócio — 2 clientes (17%)\n4. Insatisfação com suporte — 1 cliente (8%)\n\n### Perfil dos churned\n- Plano Basic: 8 (67%)\n- Plano Pro: 3 (25%)\n- Plano Enterprise: 1 (8%)\n\n**Insight:** A concentração no plano Basic sugere que o preço de renovação anual está sendo percebido como alto para clientes nesse tier. Recomendo revisar a proposta de valor ou criar um plano intermediário.', timestamp: d(1440 + 298) },
102
- ],
103
- },
104
- {
105
- id: 'conversa-6',
106
- label: 'Proposta comercial Projeto Alpha',
107
- group: 'semana',
108
- messages: [
109
- { id: 'm1', type: 'user', content: 'Precisa de ajuda para montar a proposta comercial para o Projeto Alpha. É um cliente enterprise do setor de logística.', timestamp: d(3 * 1440) },
110
- { id: 'm2', type: 'assistant', content: 'Para um cliente enterprise de logística, estruturo a proposta nos seguintes blocos:\n\n**1. Contexto e Desafios**\nIdentificar os 3 principais pain points do cliente (rastreamento, gestão de frotas, custo operacional).\n\n**2. Solução Proposta**\nDetalhar os módulos relevantes para logística: dashboard de rotas, alertas em tempo real, relatórios de KPI operacional.\n\n**3. Modelo Comercial**\n- Licença Enterprise: R$ 8.500/mês\n- Implementação e customização: R$ 45.000 (único)\n- SLA garantido: 99,9% uptime com suporte 24/7\n\n**4. ROI Estimado**\nRedução de 15-20% em custo operacional no primeiro ano.\n\n**5. Próximos Passos**\nPiloto de 30 dias sem custo para validar integração com sistema legado.\n\nDeseja que eu elabore alguma seção específica?', timestamp: d(3 * 1440 - 2) },
111
- ],
112
- },
113
- {
114
- id: 'conversa-7',
115
- label: 'KPIs do time de engenharia',
116
- group: 'semana',
117
- messages: [
118
- { id: 'm1', type: 'user', content: 'Quais KPIs devo acompanhar para o time de engenharia?', timestamp: d(4 * 1440) },
119
- { id: 'm2', type: 'assistant', content: '## KPIs Essenciais — Time de Engenharia\n\n**Velocidade e Entrega**\n- Velocity (pontos/sprint)\n- Lead time (do commit ao deploy)\n- Frequência de deploy\n- Taxa de conclusão de sprint\n\n**Qualidade**\n- Taxa de bugs em produção\n- Cobertura de testes (%)\n- MTTR — Mean Time to Recovery\n- Change failure rate\n\n**Saúde do Time**\n- Dívida técnica (story points estimados)\n- Satisfação do time (eNPS)\n- Tempo médio de code review\n\n**Negócio**\n- Tempo de entrega de features (time-to-market)\n- Uptime do sistema\n- Custo por deploy\n\nRecomendo começar com 5-7 KPIs no máximo para não sobrecarregar o processo de coleta.', timestamp: d(4 * 1440 - 2) },
120
- ],
121
- },
122
- {
123
- id: 'conversa-8',
124
- label: 'Planejamento de sprint Q2',
125
- group: 'semana',
126
- messages: [
127
- { id: 'm1', type: 'user', content: 'Me ajuda a planejar o Q2. Temos 3 sprints de 2 semanas cada.', timestamp: d(5 * 1440) },
128
- { id: 'm2', type: 'assistant', content: '## Planejamento Q2 — 3 Sprints\n\n**Sprint 1 (01–14/mai)**\n- Finalizar módulo de relatórios avançados\n- Correções críticas de UX do onboarding\n- Setup da infraestrutura para o App Mobile v2\n\n**Sprint 2 (15–28/mai)**\n- Kickoff do redesign de onboarding\n- Início da API Pública v3\n- Integração com ERP (depende de credenciais do cliente)\n\n**Sprint 3 (29/mai–11/jun)**\n- Beta fechado do App Mobile v2\n- Estabilização da API v3\n- Testes de carga e segurança\n\n**Capacidade estimada:** 85 pontos/sprint × 3 = 255 pontos no Q2\n\nSugestão: reserve 15% da capacidade de cada sprint para bugs e dívida técnica.', timestamp: d(5 * 1440 - 2) },
129
- ],
130
- },
131
- ];
132
-
133
- const GROUP_CONFIG = [
134
- { id: 'hoje', label: 'Hoje' },
135
- { id: 'ontem', label: 'Ontem' },
136
- { id: 'semana', label: 'Esta semana' },
137
- ];
138
-
139
- // ─── Component ───────────────────────────────────────────────────────────────
140
-
141
- interface AssistantPageProps {
142
- user: { email: string } | null;
143
- onLogout: () => void;
144
- }
145
-
146
- export function AssistantPage({ user, onLogout }: AssistantPageProps) {
147
- const navigate = useNavigate();
148
- const { sidebarExpanded, setSidebarExpanded } = useLayout();
149
-
150
- const [conversations, setConversations] = useState<Conversation[]>(INITIAL_CONVERSATIONS);
151
- const [selectedId, setSelectedId] = useState<string | null>(null);
152
- const [searchValue, setSearchValue] = useState('');
153
- const [deleteTarget, setDeleteTarget] = useState<Conversation | null>(null);
154
- const [renameTarget, setRenameTarget] = useState<Conversation | null>(null);
155
- const [renameValue, setRenameValue] = useState('');
156
-
157
- useEffect(() => {
158
- if (!sidebarExpanded) setSidebarExpanded(true);
159
- }, []);
160
-
161
- const selectedConversation = conversations.find((c) => c.id === selectedId) ?? null;
162
-
163
- const navigationGroups = useMemo(() => {
164
- const query = searchValue.toLowerCase();
165
- return GROUP_CONFIG.map((group) => ({
166
- id: group.id,
167
- label: group.label,
168
- icon: MessageSquare,
169
- items: conversations
170
- .filter((c) => c.group === group.id)
171
- .filter((c) => !query || c.label.toLowerCase().includes(query))
172
- .map((c) => ({
173
- path: `/assistente/${c.id}`,
174
- label: c.label,
175
- actions: [
176
- {
177
- label: 'Renomear',
178
- icon: FileEdit,
179
- onClick: () => {
180
- setRenameTarget(c);
181
- setRenameValue(c.label);
182
- },
183
- },
184
- {
185
- label: 'Excluir',
186
- icon: Trash2,
187
- onClick: () => setDeleteTarget(c),
188
- variant: 'destructive' as const,
189
- },
190
- ],
191
- })),
192
- })).filter((g) => g.items.length > 0);
193
- }, [conversations, searchValue]);
194
-
195
- const handleSelectConversation = (path: string) => {
196
- if (path.startsWith('/assistente/')) {
197
- setSelectedId(path.replace('/assistente/', ''));
198
- } else {
199
- navigate(path);
200
- }
201
- };
202
-
203
- const handleDelete = () => {
204
- if (!deleteTarget) return;
205
- setConversations((prev) => prev.filter((c) => c.id !== deleteTarget.id));
206
- if (selectedId === deleteTarget.id) setSelectedId(null);
207
- setDeleteTarget(null);
208
- };
209
-
210
- const handleRename = () => {
211
- if (!renameTarget || !renameValue.trim()) return;
212
- setConversations((prev) =>
213
- prev.map((c) => c.id === renameTarget.id ? { ...c, label: renameValue.trim() } : c)
214
- );
215
- setRenameTarget(null);
216
- };
217
-
218
- const sidebarProps = {
219
- width: 320,
220
- fixedArea: {
221
- show: true,
222
- icon: Plus,
223
- onClick: () => setSelectedId(null),
224
- content: (
225
- <Button variant="secondary" className="w-full font-semibold" onClick={() => setSelectedId(null)}>
226
- <Plus className="w-4 h-4 mr-2" />
227
- Nova Conversa
228
- </Button>
229
- ),
230
- },
231
- search: {
232
- show: true,
233
- placeholder: 'Buscar conversas...',
234
- value: searchValue,
235
- onChange: setSearchValue,
236
- },
237
- navigationGroups,
238
- location: { pathname: selectedId ? `/assistente/${selectedId}` : '/assistente' },
239
- navigate: handleSelectConversation,
240
- };
241
-
242
- return (
243
- <>
244
- <AppLayout user={user} onLogout={onLogout} sidebarVariant="assistant" sidebarProps={sidebarProps}>
245
- <div
246
- style={{ paddingLeft: sidebarExpanded ? '320px' : '80px' }}
247
- className="flex-1 flex flex-col overflow-hidden transition-all duration-300"
248
- >
249
- <Header
250
- breadcrumbs={[
251
- { label: 'Design System', href: '/home' },
252
- { label: selectedConversation?.label ?? 'Nova Conversa' },
253
- ]}
254
- renderLink={(href: string, props: any) => <Link to={href} {...props} />}
255
- actions={[
256
- {
257
- id: 'back',
258
- label: 'Voltar',
259
- icon: <ArrowLeft className="w-4 h-4" />,
260
- onClick: () => navigate('/home'),
261
- className: 'bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground',
262
- },
263
- ]}
264
- />
265
- <main className="flex-1 overflow-hidden bg-muted">
266
- <XerticaAssistant
267
- key={selectedId ?? 'new'}
268
- mode="fullPage"
269
- demoMode={true}
270
- userName="Ariel Santos"
271
- responseGenerator={generateDemoResponse}
272
- initialMessages={selectedConversation?.messages as any}
273
- richSuggestions={richSuggestions}
274
- feedbackOptions={feedbackOptions}
275
- showHistory={false}
276
- showFavorites={false}
277
- onNavigateSettings={() => navigate('/settings')}
278
- onEvaluation={(messageId, type, reason) => {
279
- console.log(`Avaliação recebida: ${type} na mensagem ${messageId}. Motivo: ${reason}`);
280
- }}
281
- />
282
- </main>
283
- </div>
284
- </AppLayout>
285
-
286
- {/* Modal: Excluir conversa */}
287
- <AlertDialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
288
- <AlertDialogContent>
289
- <AlertDialogHeader>
290
- <AlertDialogTitle>Excluir conversa</AlertDialogTitle>
291
- <AlertDialogDescription>
292
- Tem certeza que deseja excluir <strong>"{deleteTarget?.label}"</strong>? Esta ação não pode ser desfeita.
293
- </AlertDialogDescription>
294
- </AlertDialogHeader>
295
- <AlertDialogFooter>
296
- <AlertDialogCancel>Cancelar</AlertDialogCancel>
297
- <AlertDialogAction onClick={handleDelete} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
298
- Excluir
299
- </AlertDialogAction>
300
- </AlertDialogFooter>
301
- </AlertDialogContent>
302
- </AlertDialog>
303
-
304
- {/* Modal: Renomear conversa */}
305
- <Dialog open={!!renameTarget} onOpenChange={(open) => !open && setRenameTarget(null)}>
306
- <DialogContent>
307
- <DialogHeader>
308
- <DialogTitle>Renomear conversa</DialogTitle>
309
- </DialogHeader>
310
- <div className="space-y-2 py-2">
311
- <Label htmlFor="rename-input">Nome da conversa</Label>
312
- <Input
313
- id="rename-input"
314
- value={renameValue}
315
- onChange={(e) => setRenameValue(e.target.value)}
316
- onKeyDown={(e) => e.key === 'Enter' && handleRename()}
317
- autoFocus
318
- />
319
- </div>
320
- <DialogFooter>
321
- <Button variant="outline" onClick={() => setRenameTarget(null)}>Cancelar</Button>
322
- <Button onClick={handleRename} disabled={!renameValue.trim()}>Salvar</Button>
323
- </DialogFooter>
324
- </DialogContent>
325
- </Dialog>
326
- </>
327
- );
328
- }
1
+ import { useState, useMemo, useEffect } from 'react';
2
+ import { useNavigate, Link } from 'react-router-dom';
3
+ import { XerticaAssistant, generateDemoResponse } from 'xertica-ui/assistant';
4
+ import { useLayout } from 'xertica-ui/hooks';
5
+ import { Header } from 'xertica-ui/layout';
6
+ import {
7
+ Button,
8
+ AlertDialog, AlertDialogAction, AlertDialogCancel,
9
+ AlertDialogContent, AlertDialogDescription, AlertDialogFooter,
10
+ AlertDialogHeader, AlertDialogTitle,
11
+ Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle,
12
+ Input, Label,
13
+ } from 'xertica-ui/ui';
14
+ import { AppLayout } from '../app/components/AppLayout';
15
+ import { ArrowLeft, Plus, MessageSquare, Trash2, FileEdit } from 'lucide-react';
16
+
17
+ // ─── Types ───────────────────────────────────────────────────────────────────
18
+
19
+ interface ChatMessage {
20
+ id: string;
21
+ type: 'user' | 'assistant';
22
+ content: string;
23
+ timestamp: Date;
24
+ }
25
+
26
+ interface Conversation {
27
+ id: string;
28
+ label: string;
29
+ group: 'hoje' | 'ontem' | 'semana';
30
+ messages: ChatMessage[];
31
+ }
32
+
33
+ // ─── Data ────────────────────────────────────────────────────────────────────
34
+
35
+ const richSuggestions = [
36
+ { id: 'chart-1', text: 'Ver análise de performance' },
37
+ { id: 'table-1', text: 'Gerar relatório de projetos' },
38
+ { id: 'doc-1', text: 'Criar documento de requisitos' },
39
+ { id: 'pod-1', text: 'Gerar podcast do resumo diário' },
40
+ ];
41
+
42
+ const feedbackOptions = [
43
+ 'Não era o que eu procurava',
44
+ 'Informação incorreta',
45
+ 'Resposta incompleta',
46
+ ];
47
+
48
+ const d = (offsetMinutes: number) => {
49
+ const t = new Date();
50
+ t.setMinutes(t.getMinutes() - offsetMinutes);
51
+ return t;
52
+ };
53
+
54
+ const INITIAL_CONVERSATIONS: Conversation[] = [
55
+ {
56
+ id: 'conversa-1',
57
+ label: 'Análise de dados de vendas Q1',
58
+ group: 'hoje',
59
+ messages: [
60
+ { id: 'm1', type: 'user', content: 'Preciso de uma análise dos dados de vendas do primeiro trimestre. Tivemos crescimento em algumas regiões mas queda em outras.', timestamp: d(60) },
61
+ { id: 'm2', type: 'assistant', content: 'Com base nos dados do Q1, identifiquei os seguintes padrões:\n\n**Regiões com crescimento:**\n- Sudeste: +18% comparado ao Q1 do ano anterior\n- Sul: +12%\n\n**Regiões com queda:**\n- Norte: -8%\n- Nordeste: -4%\n\nO crescimento no Sudeste foi impulsionado principalmente pelo aumento no ticket médio (+22%), enquanto a queda no Norte está correlacionada com a redução de representantes comerciais ativos na região. Recomendo aumentar a cobertura comercial no Norte e Nordeste para o Q2.', timestamp: d(58) },
62
+ { id: 'm3', type: 'user', content: 'Que ações específicas você recomenda para o Norte?', timestamp: d(55) },
63
+ { id: 'm4', type: 'assistant', content: 'Para reverter a queda no Norte, recomendo:\n\n1. **Contratar 2 representantes regionais** focados nos estados do Pará e Amazonas\n2. **Programa de incentivo para distribuidores locais** com bonificação por volume trimestral\n3. **Campanhas segmentadas** com preços ajustados ao poder aquisitivo regional\n4. **Visitas presenciais quinzenais** nos 5 maiores clientes da região\n\nEssas ações têm potencial de recuperar 6-8% das vendas já no Q2.', timestamp: d(53) },
64
+ ],
65
+ },
66
+ {
67
+ id: 'conversa-2',
68
+ label: 'Relatório de performance mensal',
69
+ group: 'hoje',
70
+ messages: [
71
+ { id: 'm1', type: 'user', content: 'Gera um relatório de performance do time de engenharia para o mês de abril.', timestamp: d(120) },
72
+ { id: 'm2', type: 'assistant', content: '# Relatório de Performance — Abril\n\n**Time de Engenharia**\n\n## Entregas\n- 42 tarefas concluídas (meta: 38) ✅\n- 3 sprints fechados dentro do prazo\n- Velocity médio: 87 pontos/sprint\n\n## Qualidade\n- Taxa de bugs em produção: 0,8% (melhora de 0,3pp vs março)\n- Cobertura de testes: 78%\n- Tempo médio de resolução de incidentes: 2h 15min\n\n## Destaques\n- Deploy do módulo de relatórios avançados (2 semanas antes do prazo)\n- Redução de 40% no tempo de build do pipeline\n\n## Pontos de atenção\n- Dívida técnica no módulo de autenticação precisa de endereçamento no Q2', timestamp: d(118) },
73
+ ],
74
+ },
75
+ {
76
+ id: 'conversa-3',
77
+ label: 'Resumo das reuniões da semana',
78
+ group: 'ontem',
79
+ messages: [
80
+ { id: 'm1', type: 'user', content: 'Resume as principais decisões tomadas nas reuniões desta semana.', timestamp: d(1440 + 60) },
81
+ { id: 'm2', type: 'assistant', content: '## Decisões da Semana\n\n**Segunda — Planejamento Q2**\n- Meta de receita: R$ 4,2M (+15% vs Q1)\n- Novo produto B2B entra em beta em junho\n- Contratação de 3 devs aprovada para maio\n\n**Quarta — Review de Produto**\n- Funcionalidade de relatórios vai para produção na sexta\n- UX do onboarding será redesenhado (kickoff em 15/05)\n- Integração com ERP do cliente Alfa postergada para julho\n\n**Sexta — All Hands**\n- Empresa atingiu 500 clientes ativos 🎉\n- Novo programa de equity para colaboradores aprovado pelo board\n- Hackathon interno marcado para 20-21 de junho', timestamp: d(1440 + 58) },
82
+ { id: 'm3', type: 'user', content: 'Quando é o kickoff do redesign de UX exatamente?', timestamp: d(1440 + 50) },
83
+ { id: 'm4', type: 'assistant', content: 'O kickoff do redesign do onboarding está marcado para **15 de maio**, conforme decidido na reunião de Review de Produto de quarta-feira. O time de produto e design estará presente, e foi solicitado que o lead de engenharia frontend também participe.', timestamp: d(1440 + 48) },
84
+ ],
85
+ },
86
+ {
87
+ id: 'conversa-4',
88
+ label: 'Dashboard de projetos ativos',
89
+ group: 'ontem',
90
+ messages: [
91
+ { id: 'm1', type: 'user', content: 'Quais projetos estão ativos agora e qual o status de cada um?', timestamp: d(1440 + 180) },
92
+ { id: 'm2', type: 'assistant', content: '## Projetos Ativos\n\n| Projeto | Status | Prazo | Responsável |\n|---|---|---|---|\n| Portal do Cliente | 🟢 No prazo | 30/05 | Ana Costa |\n| Integração ERP | 🟡 Em risco | 15/05 | Bruno Lima |\n| App Mobile v2 | 🟢 No prazo | 30/06 | Carla Melo |\n| Redesign Onboarding | 🔵 Iniciando | 30/07 | Diana Park |\n| API Pública v3 | 🟡 Em risco | 01/06 | Eduardo Cruz |\n\n**Projetos em risco:** A Integração ERP está aguardando credenciais do cliente Alfa há 10 dias. A API v3 tem bloqueio técnico na autenticação OAuth que precisa de decisão arquitetural.', timestamp: d(1440 + 178) },
93
+ ],
94
+ },
95
+ {
96
+ id: 'conversa-5',
97
+ label: 'Análise de churn de clientes',
98
+ group: 'ontem',
99
+ messages: [
100
+ { id: 'm1', type: 'user', content: 'Analisa o churn do mês passado. Tivemos 12 cancelamentos.', timestamp: d(1440 + 300) },
101
+ { id: 'm2', type: 'assistant', content: '## Análise de Churn — Abril\n\n**12 cancelamentos** representam uma taxa de churn de **2,4%** (base de 500 clientes).\n\n### Principais motivos\n1. Preço / custo-benefício — 5 clientes (42%)\n2. Migração para concorrente — 4 clientes (33%)\n3. Encerramento do negócio — 2 clientes (17%)\n4. Insatisfação com suporte — 1 cliente (8%)\n\n### Perfil dos churned\n- Plano Basic: 8 (67%)\n- Plano Pro: 3 (25%)\n- Plano Enterprise: 1 (8%)\n\n**Insight:** A concentração no plano Basic sugere que o preço de renovação anual está sendo percebido como alto para clientes nesse tier. Recomendo revisar a proposta de valor ou criar um plano intermediário.', timestamp: d(1440 + 298) },
102
+ ],
103
+ },
104
+ {
105
+ id: 'conversa-6',
106
+ label: 'Proposta comercial Projeto Alpha',
107
+ group: 'semana',
108
+ messages: [
109
+ { id: 'm1', type: 'user', content: 'Precisa de ajuda para montar a proposta comercial para o Projeto Alpha. É um cliente enterprise do setor de logística.', timestamp: d(3 * 1440) },
110
+ { id: 'm2', type: 'assistant', content: 'Para um cliente enterprise de logística, estruturo a proposta nos seguintes blocos:\n\n**1. Contexto e Desafios**\nIdentificar os 3 principais pain points do cliente (rastreamento, gestão de frotas, custo operacional).\n\n**2. Solução Proposta**\nDetalhar os módulos relevantes para logística: dashboard de rotas, alertas em tempo real, relatórios de KPI operacional.\n\n**3. Modelo Comercial**\n- Licença Enterprise: R$ 8.500/mês\n- Implementação e customização: R$ 45.000 (único)\n- SLA garantido: 99,9% uptime com suporte 24/7\n\n**4. ROI Estimado**\nRedução de 15-20% em custo operacional no primeiro ano.\n\n**5. Próximos Passos**\nPiloto de 30 dias sem custo para validar integração com sistema legado.\n\nDeseja que eu elabore alguma seção específica?', timestamp: d(3 * 1440 - 2) },
111
+ ],
112
+ },
113
+ {
114
+ id: 'conversa-7',
115
+ label: 'KPIs do time de engenharia',
116
+ group: 'semana',
117
+ messages: [
118
+ { id: 'm1', type: 'user', content: 'Quais KPIs devo acompanhar para o time de engenharia?', timestamp: d(4 * 1440) },
119
+ { id: 'm2', type: 'assistant', content: '## KPIs Essenciais — Time de Engenharia\n\n**Velocidade e Entrega**\n- Velocity (pontos/sprint)\n- Lead time (do commit ao deploy)\n- Frequência de deploy\n- Taxa de conclusão de sprint\n\n**Qualidade**\n- Taxa de bugs em produção\n- Cobertura de testes (%)\n- MTTR — Mean Time to Recovery\n- Change failure rate\n\n**Saúde do Time**\n- Dívida técnica (story points estimados)\n- Satisfação do time (eNPS)\n- Tempo médio de code review\n\n**Negócio**\n- Tempo de entrega de features (time-to-market)\n- Uptime do sistema\n- Custo por deploy\n\nRecomendo começar com 5-7 KPIs no máximo para não sobrecarregar o processo de coleta.', timestamp: d(4 * 1440 - 2) },
120
+ ],
121
+ },
122
+ {
123
+ id: 'conversa-8',
124
+ label: 'Planejamento de sprint Q2',
125
+ group: 'semana',
126
+ messages: [
127
+ { id: 'm1', type: 'user', content: 'Me ajuda a planejar o Q2. Temos 3 sprints de 2 semanas cada.', timestamp: d(5 * 1440) },
128
+ { id: 'm2', type: 'assistant', content: '## Planejamento Q2 — 3 Sprints\n\n**Sprint 1 (01–14/mai)**\n- Finalizar módulo de relatórios avançados\n- Correções críticas de UX do onboarding\n- Setup da infraestrutura para o App Mobile v2\n\n**Sprint 2 (15–28/mai)**\n- Kickoff do redesign de onboarding\n- Início da API Pública v3\n- Integração com ERP (depende de credenciais do cliente)\n\n**Sprint 3 (29/mai–11/jun)**\n- Beta fechado do App Mobile v2\n- Estabilização da API v3\n- Testes de carga e segurança\n\n**Capacidade estimada:** 85 pontos/sprint × 3 = 255 pontos no Q2\n\nSugestão: reserve 15% da capacidade de cada sprint para bugs e dívida técnica.', timestamp: d(5 * 1440 - 2) },
129
+ ],
130
+ },
131
+ ];
132
+
133
+ const GROUP_CONFIG = [
134
+ { id: 'hoje', label: 'Hoje' },
135
+ { id: 'ontem', label: 'Ontem' },
136
+ { id: 'semana', label: 'Esta semana' },
137
+ ];
138
+
139
+ // ─── Component ───────────────────────────────────────────────────────────────
140
+
141
+ interface AssistantPageProps {
142
+ user: { email: string } | null;
143
+ onLogout: () => void;
144
+ }
145
+
146
+ export function AssistantPage({ user, onLogout }: AssistantPageProps) {
147
+ const navigate = useNavigate();
148
+ const { sidebarExpanded, setSidebarExpanded } = useLayout();
149
+
150
+ const [conversations, setConversations] = useState<Conversation[]>(INITIAL_CONVERSATIONS);
151
+ const [selectedId, setSelectedId] = useState<string | null>(null);
152
+ const [searchValue, setSearchValue] = useState('');
153
+ const [deleteTarget, setDeleteTarget] = useState<Conversation | null>(null);
154
+ const [renameTarget, setRenameTarget] = useState<Conversation | null>(null);
155
+ const [renameValue, setRenameValue] = useState('');
156
+
157
+ useEffect(() => {
158
+ if (!sidebarExpanded) setSidebarExpanded(true);
159
+ }, []);
160
+
161
+ const selectedConversation = conversations.find((c) => c.id === selectedId) ?? null;
162
+
163
+ const navigationGroups = useMemo(() => {
164
+ const query = searchValue.toLowerCase();
165
+ return GROUP_CONFIG.map((group) => ({
166
+ id: group.id,
167
+ label: group.label,
168
+ icon: MessageSquare,
169
+ items: conversations
170
+ .filter((c) => c.group === group.id)
171
+ .filter((c) => !query || c.label.toLowerCase().includes(query))
172
+ .map((c) => ({
173
+ path: `/assistente/${c.id}`,
174
+ label: c.label,
175
+ actions: [
176
+ {
177
+ label: 'Renomear',
178
+ icon: FileEdit,
179
+ onClick: () => {
180
+ setRenameTarget(c);
181
+ setRenameValue(c.label);
182
+ },
183
+ },
184
+ {
185
+ label: 'Excluir',
186
+ icon: Trash2,
187
+ onClick: () => setDeleteTarget(c),
188
+ variant: 'destructive' as const,
189
+ },
190
+ ],
191
+ })),
192
+ })).filter((g) => g.items.length > 0);
193
+ }, [conversations, searchValue]);
194
+
195
+ const handleSelectConversation = (path: string) => {
196
+ if (path.startsWith('/assistente/')) {
197
+ setSelectedId(path.replace('/assistente/', ''));
198
+ } else {
199
+ navigate(path);
200
+ }
201
+ };
202
+
203
+ const handleDelete = () => {
204
+ if (!deleteTarget) return;
205
+ setConversations((prev) => prev.filter((c) => c.id !== deleteTarget.id));
206
+ if (selectedId === deleteTarget.id) setSelectedId(null);
207
+ setDeleteTarget(null);
208
+ };
209
+
210
+ const handleRename = () => {
211
+ if (!renameTarget || !renameValue.trim()) return;
212
+ setConversations((prev) =>
213
+ prev.map((c) => c.id === renameTarget.id ? { ...c, label: renameValue.trim() } : c)
214
+ );
215
+ setRenameTarget(null);
216
+ };
217
+
218
+ const sidebarProps = {
219
+ width: 320,
220
+ fixedArea: {
221
+ show: true,
222
+ icon: Plus,
223
+ onClick: () => setSelectedId(null),
224
+ content: (
225
+ <Button variant="secondary" className="w-full font-semibold" onClick={() => setSelectedId(null)}>
226
+ <Plus className="w-4 h-4 mr-2" />
227
+ Nova Conversa
228
+ </Button>
229
+ ),
230
+ },
231
+ search: {
232
+ show: true,
233
+ placeholder: 'Buscar conversas...',
234
+ value: searchValue,
235
+ onChange: setSearchValue,
236
+ },
237
+ navigationGroups,
238
+ location: { pathname: selectedId ? `/assistente/${selectedId}` : '/assistente' },
239
+ navigate: handleSelectConversation,
240
+ };
241
+
242
+ return (
243
+ <>
244
+ <AppLayout user={user} onLogout={onLogout} sidebarVariant="assistant" sidebarProps={sidebarProps}>
245
+ <div
246
+ style={{ paddingLeft: sidebarExpanded ? '320px' : '80px' }}
247
+ className="flex-1 flex flex-col overflow-hidden transition-all duration-300"
248
+ >
249
+ <Header
250
+ breadcrumbs={[
251
+ { label: 'Design System', href: '/home' },
252
+ { label: selectedConversation?.label ?? 'Nova Conversa' },
253
+ ]}
254
+ renderLink={(href: string, props: any) => <Link to={href} {...props} />}
255
+ actions={[
256
+ {
257
+ id: 'back',
258
+ label: 'Voltar',
259
+ icon: <ArrowLeft className="w-4 h-4" />,
260
+ onClick: () => navigate('/home'),
261
+ className: 'bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground',
262
+ },
263
+ ]}
264
+ />
265
+ <main className="flex-1 overflow-hidden bg-muted">
266
+ <XerticaAssistant
267
+ key={selectedId ?? 'new'}
268
+ mode="fullPage"
269
+ demoMode={true}
270
+ userName="Ariel Santos"
271
+ responseGenerator={generateDemoResponse}
272
+ initialMessages={selectedConversation?.messages as any}
273
+ richSuggestions={richSuggestions}
274
+ feedbackOptions={feedbackOptions}
275
+ showHistory={false}
276
+ showFavorites={false}
277
+ onNavigateSettings={() => navigate('/settings')}
278
+ onEvaluation={(messageId, type, reason) => {
279
+ console.log(`Avaliação recebida: ${type} na mensagem ${messageId}. Motivo: ${reason}`);
280
+ }}
281
+ />
282
+ </main>
283
+ </div>
284
+ </AppLayout>
285
+
286
+ {/* Modal: Excluir conversa */}
287
+ <AlertDialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
288
+ <AlertDialogContent>
289
+ <AlertDialogHeader>
290
+ <AlertDialogTitle>Excluir conversa</AlertDialogTitle>
291
+ <AlertDialogDescription>
292
+ Tem certeza que deseja excluir <strong>"{deleteTarget?.label}"</strong>? Esta ação não pode ser desfeita.
293
+ </AlertDialogDescription>
294
+ </AlertDialogHeader>
295
+ <AlertDialogFooter>
296
+ <AlertDialogCancel>Cancelar</AlertDialogCancel>
297
+ <AlertDialogAction onClick={handleDelete} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
298
+ Excluir
299
+ </AlertDialogAction>
300
+ </AlertDialogFooter>
301
+ </AlertDialogContent>
302
+ </AlertDialog>
303
+
304
+ {/* Modal: Renomear conversa */}
305
+ <Dialog open={!!renameTarget} onOpenChange={(open) => !open && setRenameTarget(null)}>
306
+ <DialogContent>
307
+ <DialogHeader>
308
+ <DialogTitle>Renomear conversa</DialogTitle>
309
+ </DialogHeader>
310
+ <div className="space-y-2 py-2">
311
+ <Label htmlFor="rename-input">Nome da conversa</Label>
312
+ <Input
313
+ id="rename-input"
314
+ value={renameValue}
315
+ onChange={(e) => setRenameValue(e.target.value)}
316
+ onKeyDown={(e) => e.key === 'Enter' && handleRename()}
317
+ autoFocus
318
+ />
319
+ </div>
320
+ <DialogFooter>
321
+ <Button variant="outline" onClick={() => setRenameTarget(null)}>Cancelar</Button>
322
+ <Button onClick={handleRename} disabled={!renameValue.trim()}>Salvar</Button>
323
+ </DialogFooter>
324
+ </DialogContent>
325
+ </Dialog>
326
+ </>
327
+ );
328
+ }