xertica-ui 2.1.3 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (404) hide show
  1. package/CHANGELOG.md +15 -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/components/assistant/index.ts +6 -6
  6. package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +97 -0
  7. package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -0
  8. package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -0
  9. package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +86 -0
  10. package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +77 -0
  11. package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +573 -0
  12. package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +65 -0
  13. package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -0
  14. package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +98 -0
  15. package/components/assistant/xertica-assistant/parts/index.ts +16 -0
  16. package/components/assistant/xertica-assistant/types.ts +139 -0
  17. package/components/assistant/xertica-assistant/use-assistant.ts +5 -10
  18. package/components/assistant/xertica-assistant/xertica-assistant.tsx +125 -1096
  19. package/components/blocks/card-patterns/ActivityCard.tsx +72 -72
  20. package/components/blocks/card-patterns/FeatureCard.tsx +100 -100
  21. package/components/blocks/card-patterns/NotificationCard.tsx +127 -127
  22. package/components/blocks/card-patterns/ProfileCard.tsx +84 -84
  23. package/components/blocks/card-patterns/ProjectCard.tsx +89 -89
  24. package/components/blocks/card-patterns/QuickActionCard.tsx +62 -62
  25. package/components/blocks/card-patterns/card-patterns.stories.tsx +445 -445
  26. package/components/blocks/card-patterns/index.ts +17 -17
  27. package/components/blocks/index.ts +1 -1
  28. package/components/brand/index.ts +6 -6
  29. package/components/brand/theme-toggle/ThemeToggle.tsx +8 -27
  30. package/components/brand/xertica-provider/XerticaProvider.tsx +48 -48
  31. package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
  32. package/components/brand/xertica-provider/xertica-provider.test.tsx +52 -52
  33. package/components/examples/MapExamples.tsx +282 -282
  34. package/components/examples/SimpleFilterableMap.tsx +191 -191
  35. package/components/examples/index.ts +51 -51
  36. package/components/figma/ImageWithFallback.tsx +27 -27
  37. package/components/hooks/index.ts +10 -7
  38. package/components/hooks/use-layout-shortcuts.ts +46 -0
  39. package/components/index.ts +5 -5
  40. package/components/layout/header/header.test.tsx +8 -8
  41. package/components/layout/header/header.tsx +4 -4
  42. package/components/layout/index.ts +2 -2
  43. package/components/layout/sidebar/sidebar.mdx +1 -1
  44. package/components/layout/sidebar/sidebar.test.tsx +11 -11
  45. package/components/layout/sidebar/sidebar.tsx +1 -31
  46. package/components/layout/sidebar/use-sidebar.ts +2 -11
  47. package/components/media/FloatingMediaWrapper.tsx +11 -11
  48. package/components/media/audio-player/AudioPlayer.tsx +140 -215
  49. package/components/media/audio-player/use-audio-player.ts +298 -0
  50. package/components/media/index.ts +3 -3
  51. package/components/pages/home-content/HomeContent.tsx +7 -7
  52. package/components/pages/home-content/home-content.mdx +62 -62
  53. package/components/pages/home-page/HomePage.stories.tsx +39 -39
  54. package/components/pages/home-page/home-page.mdx +53 -53
  55. package/components/pages/index.ts +8 -8
  56. package/components/pages/template-content/template-content.mdx +61 -61
  57. package/components/pages/template-page/TemplatePage.stories.tsx +39 -39
  58. package/components/pages/template-page/template-page.mdx +53 -53
  59. package/components/public-api-smoke.test.tsx +52 -52
  60. package/components/shared/CustomTooltipContent.tsx +52 -0
  61. package/components/shared/assistant-utils.ts +43 -43
  62. package/components/ui/accordion/accordion.mdx +8 -8
  63. package/components/ui/accordion/accordion.stories.tsx +53 -53
  64. package/components/ui/alert/alert.mdx +8 -8
  65. package/components/ui/alert-dialog/alert-dialog.mdx +8 -8
  66. package/components/ui/aspect-ratio/aspect-ratio.mdx +8 -8
  67. package/components/ui/assistant-chart/assistant-chart.mdx +8 -8
  68. package/components/ui/avatar/avatar.mdx +8 -8
  69. package/components/ui/badge/badge.mdx +8 -8
  70. package/components/ui/badge/badge.tsx +9 -9
  71. package/components/ui/breadcrumb/breadcrumb.mdx +8 -8
  72. package/components/ui/button/button.mdx +8 -8
  73. package/components/ui/calendar/calendar.mdx +8 -8
  74. package/components/ui/calendar/calendar.tsx +258 -258
  75. package/components/ui/card/card.mdx +8 -8
  76. package/components/ui/card/card.stories.tsx +245 -245
  77. package/components/ui/carousel/carousel.mdx +8 -8
  78. package/components/ui/chart/chart.mdx +8 -8
  79. package/components/ui/chart/chart.stories.tsx +1303 -1303
  80. package/components/ui/chart/chart.test.tsx +154 -154
  81. package/components/ui/chart/chart.tsx +2367 -2367
  82. package/components/ui/checkbox/checkbox.mdx +8 -8
  83. package/components/ui/checkbox/checkbox.stories.tsx +20 -20
  84. package/components/ui/collapsible/collapsible.mdx +8 -8
  85. package/components/ui/command/command.mdx +8 -8
  86. package/components/ui/context-menu/context-menu.mdx +8 -8
  87. package/components/ui/dialog/dialog.mdx +8 -8
  88. package/components/ui/drawer/drawer.mdx +8 -8
  89. package/components/ui/dropdown-menu/dropdown-menu.mdx +8 -8
  90. package/components/ui/empty/empty.mdx +8 -8
  91. package/components/ui/file-upload/file-upload.mdx +8 -8
  92. package/components/ui/google-maps-loader/google-maps-loader.tsx +2 -2
  93. package/components/ui/hover-card/hover-card.mdx +8 -8
  94. package/components/ui/input/input.mdx +8 -8
  95. package/components/ui/input-otp/input-otp.mdx +8 -8
  96. package/components/ui/input-otp/input-otp.stories.tsx +6 -6
  97. package/components/ui/label/label.mdx +8 -8
  98. package/components/ui/map/map.mdx +8 -8
  99. package/components/ui/map/map.stories.tsx +51 -51
  100. package/components/ui/map/map.tsx +2 -2
  101. package/components/ui/menubar/menubar.mdx +8 -8
  102. package/components/ui/navigation-menu/navigation-menu.mdx +8 -8
  103. package/components/ui/notification-badge/notification-badge.mdx +8 -8
  104. package/components/ui/pagination/pagination.mdx +8 -8
  105. package/components/ui/popover/popover.mdx +8 -8
  106. package/components/ui/progress/progress.mdx +8 -8
  107. package/components/ui/progress/progress.tsx +68 -68
  108. package/components/ui/radio-group/radio-group.mdx +8 -8
  109. package/components/ui/rating/rating.mdx +8 -8
  110. package/components/ui/resizable/resizable.mdx +8 -8
  111. package/components/ui/route-map/route-map.mdx +8 -8
  112. package/components/ui/route-map/route-map.stories.tsx +54 -54
  113. package/components/ui/route-map/route-map.tsx +2 -2
  114. package/components/ui/scroll-area/scroll-area.mdx +8 -8
  115. package/components/ui/search/search.mdx +8 -8
  116. package/components/ui/select/select.mdx +8 -8
  117. package/components/ui/select/select.stories.tsx +9 -9
  118. package/components/ui/separator/separator.mdx +8 -8
  119. package/components/ui/sheet/sheet.mdx +8 -8
  120. package/components/ui/sheet/sheet.stories.tsx +95 -95
  121. package/components/ui/simple-map/simple-map.mdx +8 -8
  122. package/components/ui/simple-map/simple-map.stories.tsx +48 -48
  123. package/components/ui/skeleton/skeleton.mdx +8 -8
  124. package/components/ui/slider/slider.mdx +8 -8
  125. package/components/ui/sonner/sonner.mdx +8 -8
  126. package/components/ui/stats-card/stats-card.mdx +8 -8
  127. package/components/ui/stepper/stepper.mdx +8 -8
  128. package/components/ui/switch/switch.mdx +8 -8
  129. package/components/ui/switch/switch.stories.tsx +20 -20
  130. package/components/ui/table/table.mdx +8 -8
  131. package/components/ui/tabs/tabs.mdx +8 -8
  132. package/components/ui/tabs/tabs.stories.tsx +26 -26
  133. package/components/ui/textarea/textarea.mdx +8 -8
  134. package/components/ui/timeline/timeline.mdx +8 -8
  135. package/components/ui/toggle/toggle.mdx +8 -8
  136. package/components/ui/toggle-group/toggle-group.mdx +8 -8
  137. package/components/ui/tooltip/tooltip.mdx +8 -8
  138. package/components/ui/tree-view/tree-view.mdx +8 -8
  139. package/components.json +1512 -1512
  140. package/contexts/ApiKeyContext.tsx +72 -72
  141. package/contexts/AssistenteContext.tsx +17 -54
  142. package/contexts/BrandColorsContext.tsx +32 -43
  143. package/contexts/LanguageContext.tsx +13 -13
  144. package/contexts/LayoutContext.test.tsx +11 -11
  145. package/contexts/LayoutContext.tsx +24 -50
  146. package/contexts/ThemeContext.tsx +26 -26
  147. package/contexts/theme-data.ts +4 -4
  148. package/dist/{AssistantChart-DoZCyS5r.cjs → AssistantChart-9w31gdAb.cjs} +4 -4
  149. package/dist/{AssistantChart-CldVCVDe.cjs → AssistantChart-BAudAfne.cjs} +5 -5
  150. package/dist/{use-mobile-DRB3BQgD.cjs → AssistantChart-BAx9VQvb.cjs} +209 -1070
  151. package/dist/{AssistantChart-Cu3m7RBo.js → AssistantChart-BP8upjMk.js} +5 -5
  152. package/dist/{use-mobile-BvYdisLP.js → AssistantChart-CVko2A1W.js} +171 -1025
  153. package/dist/{AssistantChart-C_hwFRRr.js → AssistantChart-CVzmmhx4.js} +4 -4
  154. package/dist/{AudioPlayer-C12BjQBV.cjs → AudioPlayer-1ypwE2Wh.cjs} +126 -187
  155. package/dist/{AudioPlayer-DcFKRJE_.js → AudioPlayer-DuKXrCfy.js} +80 -141
  156. package/dist/CustomTooltipContent-DHjkY0ww.js +40 -0
  157. package/dist/CustomTooltipContent-c_K-DWRr.cjs +56 -0
  158. package/dist/{ThemeContext-BoH4NLfN.js → LanguageContext-BwhwC3G2.js} +27 -104
  159. package/dist/{ThemeContext-r69W20Xg.cjs → LanguageContext-DvUt5jBg.cjs} +27 -104
  160. package/dist/{LayoutContext-BvK-ggDa.cjs → LayoutContext-BDmcZfMH.cjs} +8 -20
  161. package/dist/{LayoutContext-BAql6ZRY.js → LayoutContext-dbQvdC4O.js} +8 -20
  162. package/dist/{ThemeContext-C2EwAPDt.js → ThemeContext-BbBNoFTG.js} +2 -2
  163. package/dist/{ThemeContext-vTjumZeM.cjs → ThemeContext-Cmr8Ex8H.cjs} +2 -2
  164. package/dist/ThemeContext-RTy1m2Uq.js +82 -0
  165. package/dist/ThemeContext-bSzuOit2.cjs +81 -0
  166. package/dist/VerifyEmailPage-BE-L9mB7.js +2828 -0
  167. package/dist/{VerifyEmailPage-Cwi3kbol.cjs → VerifyEmailPage-Bae2cBXT.cjs} +7 -7
  168. package/dist/VerifyEmailPage-CR7kb5df.cjs +2827 -0
  169. package/dist/{VerifyEmailPage-C0c2e5n0.js → VerifyEmailPage-C_ihbcth.js} +6 -6
  170. package/dist/VerifyEmailPage-CbgjOF0v.js +2828 -0
  171. package/dist/{VerifyEmailPage-DvMLZgFt.js → VerifyEmailPage-CdYPSJoO.js} +1 -1
  172. package/dist/{VerifyEmailPage-CYXtbKi3.cjs → VerifyEmailPage-DMBh4NM9.cjs} +1 -1
  173. package/dist/VerifyEmailPage-Dt7zgA4w.cjs +2827 -0
  174. package/dist/{XerticaProvider-CEoWMTxu.js → XerticaProvider-BITjgC5p.js} +2 -2
  175. package/dist/{XerticaProvider-CllrbMEJ.cjs → XerticaProvider-By8q3Roe.cjs} +2 -2
  176. package/dist/{XerticaProvider-cI9hSs27.cjs → XerticaProvider-CW9hpCdF.cjs} +9 -8
  177. package/dist/{XerticaProvider-DDuiIcKo.js → XerticaProvider-siSt9uG2.js} +5 -4
  178. package/dist/{LanguageSelector-D6uacAIM.cjs → XerticaXLogo-D8jf0SNv.cjs} +86 -102
  179. package/dist/{LanguageSelector-B5YfbHra.js → XerticaXLogo-fAJMy3H4.js} +87 -103
  180. package/dist/{alert-dialog-s-vmNkJ_.js → alert-dialog-iDe5VE5o.js} +3 -3
  181. package/dist/{alert-dialog-DSKByiKZ.cjs → alert-dialog-yckpaOpy.cjs} +3 -3
  182. package/dist/assistant.cjs.js +1 -1
  183. package/dist/assistant.es.js +1 -1
  184. package/dist/brand.cjs.js +2 -2
  185. package/dist/brand.es.js +2 -2
  186. package/dist/components/assistant/xertica-assistant/parts/AssistantCollapsedView.d.ts +13 -0
  187. package/dist/components/assistant/xertica-assistant/parts/AssistantConversationList.d.ts +16 -0
  188. package/dist/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.d.ts +17 -0
  189. package/dist/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.d.ts +19 -0
  190. package/dist/components/assistant/xertica-assistant/parts/AssistantHeader.d.ts +11 -0
  191. package/dist/components/assistant/xertica-assistant/parts/AssistantMessageBubble.d.ts +29 -0
  192. package/dist/components/assistant/xertica-assistant/parts/AssistantTabBar.d.ts +13 -0
  193. package/dist/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.d.ts +4 -0
  194. package/dist/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.d.ts +17 -0
  195. package/dist/components/assistant/xertica-assistant/parts/index.d.ts +16 -0
  196. package/dist/components/assistant/xertica-assistant/types.d.ts +106 -0
  197. package/dist/components/assistant/xertica-assistant/use-assistant.d.ts +1 -2
  198. package/dist/components/assistant/xertica-assistant/xertica-assistant.d.ts +2 -96
  199. package/dist/components/hooks/index.d.ts +3 -0
  200. package/dist/components/hooks/use-layout-shortcuts.d.ts +22 -0
  201. package/dist/components/media/audio-player/AudioPlayer.d.ts +4 -1
  202. package/dist/components/media/audio-player/use-audio-player.d.ts +72 -0
  203. package/dist/components/shared/CustomTooltipContent.d.ts +20 -0
  204. package/dist/components/ui/alert/alert.d.ts +1 -1
  205. package/dist/components/ui/badge/badge.d.ts +1 -1
  206. package/dist/components/ui/button/button.d.ts +2 -2
  207. package/dist/contexts/AssistenteContext.d.ts +10 -49
  208. package/dist/{google-maps-loader-Y-QkD-Li.cjs → google-maps-loader-BqsYL48U.cjs} +0 -5
  209. package/dist/{google-maps-loader-CTYySAun.js → google-maps-loader-t2IlYBzw.js} +0 -4
  210. package/dist/hooks.cjs.js +30 -10
  211. package/dist/hooks.es.js +25 -4
  212. package/dist/index-CkTUgOwX.js +8 -0
  213. package/dist/{index-COtD8bRW.cjs → index-D3RLKRAs.cjs} +1 -1
  214. package/dist/index.cjs.js +11 -11
  215. package/dist/index.es.js +11 -11
  216. package/dist/index.umd.js +454 -1027
  217. package/dist/layout.cjs.js +3 -10
  218. package/dist/layout.es.js +3 -10
  219. package/dist/media.cjs.js +1 -1
  220. package/dist/media.es.js +1 -1
  221. package/dist/pages.cjs.js +1 -1
  222. package/dist/pages.es.js +1 -1
  223. package/dist/{sidebar-CK_0ZQHj.cjs → sidebar-CVUGHOS_.cjs} +10 -57
  224. package/dist/{sidebar-CUuOvYhK.js → sidebar-CmvwjnVb.js} +10 -40
  225. package/dist/ui.cjs.js +4 -4
  226. package/dist/ui.es.js +4 -4
  227. package/dist/use-audio-player-Bkh23vQ3.js +177 -0
  228. package/dist/use-audio-player-Dn1NR9xN.cjs +176 -0
  229. package/dist/utils/color-utils.d.ts +51 -0
  230. package/dist/{xertica-assistant-dyP7KHM5.cjs → xertica-assistant-B1IaHXnB.cjs} +388 -529
  231. package/dist/xertica-assistant-BMqdyRVi.js +2082 -0
  232. package/dist/xertica-assistant-Bj3vBCq_.cjs +2081 -0
  233. package/dist/{xertica-assistant-yX1CFBBo.js → xertica-assistant-DPsESB6t.js} +390 -531
  234. package/dist/{CodeBlock-BgfYL_rD.cjs → xertica-assistant-Qp3ydksa.cjs} +51 -263
  235. package/dist/{CodeBlock-DnYNI8rQ.js → xertica-assistant-gnCJdcZY.js} +7 -219
  236. package/dist/xertica-ui.css +2 -2
  237. package/docs/architecture-improvements.md +463 -0
  238. package/docs/architecture.md +1 -1
  239. package/docs/components/assistant-chart.md +1 -1
  240. package/docs/components/audio-player.md +46 -0
  241. package/docs/components/branding.md +251 -0
  242. package/docs/components/calendar.md +154 -154
  243. package/docs/components/card-patterns.md +337 -337
  244. package/docs/components/card.md +235 -235
  245. package/docs/components/code-block.md +108 -0
  246. package/docs/components/formatted-document.md +113 -0
  247. package/docs/components/hooks.md +430 -0
  248. package/docs/components/image-with-fallback.md +106 -0
  249. package/docs/components/map-layers.md +140 -0
  250. package/docs/components/map.md +84 -84
  251. package/docs/components/modern-chat-input.md +163 -0
  252. package/docs/components/pages.md +351 -0
  253. package/docs/components/xertica-provider.md +24 -24
  254. package/docs/decision-tree.md +287 -287
  255. package/docs/doc-audit.md +223 -0
  256. package/docs/getting-started.md +154 -0
  257. package/docs/llms.md +25 -5
  258. package/docs/patterns/detail-page.md +276 -0
  259. package/docs/patterns/settings.md +346 -0
  260. package/docs/patterns/wizard.md +217 -0
  261. package/guidelines/Guidelines.md +252 -252
  262. package/hooks/useTheme.ts +3 -3
  263. package/imports/Podcast.tsx +388 -388
  264. package/imports/XerticaAi.tsx +45 -45
  265. package/imports/XerticaX.tsx +19 -19
  266. package/imports/svg-aueiaqngck.ts +11 -11
  267. package/imports/svg-v9krss1ozd.ts +16 -16
  268. package/imports/svg-vhrdofe3qe.ts +5 -5
  269. package/llms-compact.txt +327 -327
  270. package/llms.txt +160 -160
  271. package/package.json +203 -203
  272. package/styles/xertica/app-overrides/chat.css +61 -61
  273. package/styles/xertica/app-overrides/scrollbar.css +33 -33
  274. package/styles/xertica/integrations/google-maps.css +76 -76
  275. package/styles/xertica/integrations/sonner.css +73 -73
  276. package/templates/CLAUDE.md +182 -182
  277. package/templates/guidelines/Guidelines.md +325 -325
  278. package/templates/package.json +2 -2
  279. package/templates/src/features/auth/index.ts +4 -4
  280. package/templates/src/features/auth/ui/AuthPageShell.tsx +34 -34
  281. package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -70
  282. package/templates/src/features/auth/ui/LoginContent.tsx +90 -90
  283. package/templates/src/features/auth/ui/ResetPasswordContent.tsx +151 -151
  284. package/templates/src/features/auth/ui/SocialLoginButtons.tsx +59 -59
  285. package/templates/src/features/auth/ui/VerifyEmailContent.tsx +82 -82
  286. package/templates/src/features/home/index.ts +1 -1
  287. package/templates/src/features/home/ui/HomeContent.tsx +100 -100
  288. package/templates/src/features/template/index.ts +5 -5
  289. package/templates/src/features/template/ui/CrudTemplate.tsx +3 -3
  290. package/templates/src/features/template/ui/DashboardTemplate.tsx +3 -3
  291. package/templates/src/features/template/ui/FormTemplate.tsx +120 -120
  292. package/templates/src/features/template/ui/LoginTemplate.tsx +3 -3
  293. package/templates/src/pages/AssistantPage.tsx +328 -328
  294. package/templates/src/pages/ForgotPasswordPage.tsx +6 -6
  295. package/templates/src/pages/HomePage.tsx +57 -57
  296. package/templates/src/pages/LoginPage.tsx +10 -10
  297. package/templates/src/pages/ResetPasswordPage.tsx +6 -6
  298. package/templates/src/pages/TemplatePage.tsx +30 -30
  299. package/templates/src/pages/VerifyEmailPage.tsx +6 -6
  300. package/templates/src/shared/config/navigation.ts +20 -20
  301. package/templates/src/shared/lib/auth.ts +20 -20
  302. package/templates/src/shared/types/auth.ts +3 -3
  303. package/templates/tsconfig.json +5 -5
  304. package/utils/color-utils.ts +72 -0
  305. package/utils/gemini.ts +140 -140
  306. package/dist/AudioPlayer-B1lt5cPl.cjs +0 -989
  307. package/dist/AudioPlayer-BZ7bibzU.cjs +0 -982
  308. package/dist/AudioPlayer-DMcG_c7L.js +0 -990
  309. package/dist/AudioPlayer-e8LfNoqO.js +0 -983
  310. package/dist/CodeBlock-7TTgmdGG.cjs +0 -2094
  311. package/dist/CodeBlock-BeSt1h5P.js +0 -2078
  312. package/dist/CodeBlock-BlcqlA9M.cjs +0 -2094
  313. package/dist/CodeBlock-Bnmeu5ez.cjs +0 -2094
  314. package/dist/CodeBlock-BtfPlbAI.js +0 -2078
  315. package/dist/CodeBlock-CIySIuYr.js +0 -2078
  316. package/dist/CodeBlock-CuPtUM-7.cjs +0 -2094
  317. package/dist/CodeBlock-D6ffWXgc.js +0 -2078
  318. package/dist/CodeBlock-D8dcwbit.cjs +0 -2094
  319. package/dist/CodeBlock-DMZrFnlw.cjs +0 -2094
  320. package/dist/CodeBlock-DlBehYN8.js +0 -2078
  321. package/dist/CodeBlock-DvKWbSnE.cjs +0 -2094
  322. package/dist/CodeBlock-DwMCfkFY.js +0 -2078
  323. package/dist/CodeBlock-Dy6CNYyj.js +0 -2078
  324. package/dist/CodeBlock-U1pPOQI7.cjs +0 -2094
  325. package/dist/CodeBlock-f_GpNhEB.js +0 -2078
  326. package/dist/CodeBlock-oB6u8nI1.js +0 -2078
  327. package/dist/CodeBlock-tZC31B73.cjs +0 -2094
  328. package/dist/ImageWithFallback-CGtidP6B.cjs +0 -4542
  329. package/dist/ImageWithFallback-lsg3pdFg.js +0 -4508
  330. package/dist/XerticaOrbe-KL1RBHzw.cjs +0 -1354
  331. package/dist/XerticaOrbe-zwS1p2a8.js +0 -1355
  332. package/dist/XerticaProvider-6btlAlzc.js +0 -17
  333. package/dist/XerticaProvider-BNoNOxQ5.cjs +0 -16
  334. package/dist/XerticaProvider-BlY2limY.cjs +0 -38
  335. package/dist/XerticaProvider-hSwhNQex.js +0 -39
  336. package/dist/breadcrumb-CqJ7bHY5.js +0 -161
  337. package/dist/breadcrumb-m9Hb2_XN.cjs +0 -177
  338. package/dist/components/blocks/audio-player/AudioPlayer.d.ts +0 -35
  339. package/dist/components/blocks/audio-player/index.d.ts +0 -1
  340. package/dist/components/blocks/document-editor/DocumentEditor.d.ts +0 -26
  341. package/dist/components/blocks/document-editor/index.d.ts +0 -1
  342. package/dist/components/blocks/podcast-player/PodcastPlayer.d.ts +0 -41
  343. package/dist/components/blocks/podcast-player/index.d.ts +0 -1
  344. package/dist/dropdown-menu-BDB5CmQs.cjs +0 -247
  345. package/dist/dropdown-menu-DQidbKBD.js +0 -231
  346. package/dist/google-maps-loader-BFWp6VPd.js +0 -287
  347. package/dist/google-maps-loader-eS3uQ5TA.cjs +0 -287
  348. package/dist/header-Cgy6vYPk.cjs +0 -731
  349. package/dist/header-DRlT4jgI.js +0 -715
  350. package/dist/header-Dux00SI4.cjs +0 -731
  351. package/dist/header-EkGKXPsD.js +0 -715
  352. package/dist/header-WfEywpyc.cjs +0 -731
  353. package/dist/header-tifNQn2U.js +0 -715
  354. package/dist/index-BhapVLVj.js +0 -8
  355. package/dist/index-D6fxYEY8.cjs +0 -7
  356. package/dist/index-DW5tYe26.js +0 -8
  357. package/dist/input-2R4loU86.js +0 -127
  358. package/dist/input-DWANSKGb.cjs +0 -145
  359. package/dist/rich-text-editor-0mraWT5y.cjs +0 -2376
  360. package/dist/rich-text-editor-B6jMRLzk.cjs +0 -1939
  361. package/dist/rich-text-editor-B8_oYcIR.js +0 -1730
  362. package/dist/rich-text-editor-B9UbSXNb.js +0 -1203
  363. package/dist/rich-text-editor-BYuRBNBU.js +0 -2373
  364. package/dist/rich-text-editor-Bb9pySTs.cjs +0 -2374
  365. package/dist/rich-text-editor-BcL6L3cm.cjs +0 -2374
  366. package/dist/rich-text-editor-BoVZYtTs.cjs +0 -2391
  367. package/dist/rich-text-editor-CPV1lEPH.cjs +0 -1748
  368. package/dist/rich-text-editor-CoKqbCtu.cjs +0 -1799
  369. package/dist/rich-text-editor-Cw56T_mB.js +0 -2356
  370. package/dist/rich-text-editor-Cyt8qs2b.js +0 -1921
  371. package/dist/rich-text-editor-D6H84OcX.cjs +0 -1220
  372. package/dist/rich-text-editor-D76gD-QI.js +0 -2328
  373. package/dist/rich-text-editor-DKkokOnA.js +0 -1781
  374. package/dist/rich-text-editor-DNsdpN64.cjs +0 -2359
  375. package/dist/rich-text-editor-DfG8bCyY.js +0 -2358
  376. package/dist/rich-text-editor-Dxjw31Z4.js +0 -2341
  377. package/dist/rich-text-editor-DzP0Epmb.js +0 -2356
  378. package/dist/rich-text-editor-skplNlBM.cjs +0 -2345
  379. package/dist/select-Bkbr0f-Z.cjs +0 -162
  380. package/dist/select-CvIVdX2n.js +0 -145
  381. package/dist/slider-Bc5Hd0y1.js +0 -56
  382. package/dist/slider-N7hFFj6X.cjs +0 -73
  383. package/dist/tooltip-Ded96neP.cjs +0 -137
  384. package/dist/tooltip-HDOoD2-0.js +0 -120
  385. package/dist/use-mobile-B0hNy_Y6.cjs +0 -4303
  386. package/dist/use-mobile-BXuYROXM.js +0 -4202
  387. package/dist/use-mobile-Bbd51ASU.cjs +0 -4392
  388. package/dist/use-mobile-Bk6CX-TC.js +0 -4359
  389. package/dist/use-mobile-BzuxjzNX.cjs +0 -4392
  390. package/dist/use-mobile-CG2-SdXV.cjs +0 -4235
  391. package/dist/use-mobile-CKb5pqTs.js +0 -4269
  392. package/dist/use-mobile-CYuAuGDl.js +0 -4202
  393. package/dist/use-mobile-CaENcqm-.js +0 -4508
  394. package/dist/use-mobile-CbrYgJGJ.js +0 -4203
  395. package/dist/use-mobile-DMOvImGQ.cjs +0 -4542
  396. package/dist/use-mobile-DZvv7QMR.js +0 -4359
  397. package/dist/use-mobile-DdI_TXam.cjs +0 -4235
  398. package/dist/use-mobile-DlceKf8a.js +0 -4359
  399. package/dist/use-mobile-DsOnow1o.cjs +0 -4236
  400. package/dist/use-mobile-Kcj6jSnK.cjs +0 -4392
  401. package/dist/use-mobile-bnKcua_i.js +0 -4202
  402. package/dist/use-mobile-ncXBeE2z.cjs +0 -4235
  403. package/dist/{rich-text-editor-DgF8s7xW.js → rich-text-editor-BmsjY03B.js} +26 -26
  404. package/dist/{rich-text-editor-mWoaSCE4.cjs → rich-text-editor-GS2kpTAK.cjs} +26 -26
@@ -0,0 +1,573 @@
1
+ import React from 'react';
2
+ import { motion } from 'framer-motion';
3
+ import {
4
+ FileText,
5
+ Music,
6
+ Image as ImageIcon,
7
+ Radio,
8
+ Loader2,
9
+ Download,
10
+ Edit,
11
+ Search,
12
+ Folder,
13
+ Users,
14
+ ExternalLink,
15
+ Clock,
16
+ FolderOpen,
17
+ MessageSquare,
18
+ AlertCircle,
19
+ ThumbsUp,
20
+ ThumbsDown,
21
+ Copy,
22
+ Check,
23
+ } from 'lucide-react';
24
+ import {
25
+ Bar,
26
+ BarChart,
27
+ CartesianGrid,
28
+ XAxis,
29
+ } from 'recharts';
30
+ import {
31
+ ChartContainer,
32
+ ChartTooltip,
33
+ ChartTooltipContent,
34
+ ChartLegend,
35
+ ChartLegendContent,
36
+ } from '../../../ui/chart';
37
+ import {
38
+ Table,
39
+ TableBody,
40
+ TableCaption,
41
+ TableCell,
42
+ TableHead,
43
+ TableHeader,
44
+ TableRow,
45
+ } from '../../../ui/table';
46
+ import {
47
+ DropdownMenu,
48
+ DropdownMenuContent,
49
+ DropdownMenuItem,
50
+ DropdownMenuTrigger,
51
+ } from '../../../ui/dropdown-menu';
52
+ import { Button } from '../../../ui/button';
53
+ import { MarkdownMessage } from '../../markdown-message';
54
+ import { FormattedDocument } from '../../formatted-document';
55
+ import { XerticaOrbe } from '../../../brand/xertica-orbe';
56
+ import { cn } from '../../../shared/utils';
57
+ import type { Message, SearchResult } from '../types';
58
+
59
+ interface AssistantMessageBubbleProps {
60
+ msg: Message;
61
+ copiedId: string | null;
62
+ generatingPodcastId: string | null;
63
+ executingCommand: string | null;
64
+ savedSearches: string[];
65
+ enablePodcastGeneration: boolean;
66
+ feedbackOptions?: string[];
67
+ onCopyMessage: (content: string, id: string) => void;
68
+ onToggleFavorite: (id: string) => void;
69
+ onGeneratePodcast: (id: string, content: string) => void;
70
+ onDownloadDocument: (content: string, fileName: string) => void;
71
+ onDownloadPodcast: (audioUrl: string, fileName: string) => void;
72
+ onEditDocument: (content: string, title: string) => void;
73
+ onOpenSearchResult: (result: SearchResult) => void;
74
+ onExecuteSearchCommand: (
75
+ commandId: string,
76
+ query: string,
77
+ results: SearchResult[],
78
+ messageId: string,
79
+ ) => void;
80
+ onEvaluationClick: (id: string, type: 'like' | 'dislike') => void;
81
+ onOpenFeedbackDialog: (id: string, category: string | null) => void;
82
+ }
83
+
84
+ /**
85
+ * AssistantMessageBubble — Renders a single chat message with all supported content types:
86
+ * plain text, Markdown, charts, tables, documents, podcasts, and search results.
87
+ *
88
+ * Handles both user and assistant message styles, plus per-message action buttons
89
+ * (copy, like/dislike, podcast generation).
90
+ */
91
+ export function AssistantMessageBubble({
92
+ msg,
93
+ copiedId,
94
+ generatingPodcastId,
95
+ executingCommand,
96
+ savedSearches,
97
+ enablePodcastGeneration,
98
+ feedbackOptions,
99
+ onCopyMessage,
100
+ onToggleFavorite,
101
+ onGeneratePodcast,
102
+ onDownloadDocument,
103
+ onDownloadPodcast,
104
+ onEditDocument,
105
+ onOpenSearchResult,
106
+ onExecuteSearchCommand,
107
+ onEvaluationClick,
108
+ onOpenFeedbackDialog,
109
+ }: AssistantMessageBubbleProps) {
110
+ return (
111
+ <motion.div
112
+ key={msg.id}
113
+ initial={{ opacity: 0, y: 10 }}
114
+ animate={{ opacity: 1, y: 0 }}
115
+ className={`flex gap-2 w-full min-w-0 ${msg.type === 'user' ? 'justify-end' : 'justify-start'}`}
116
+ >
117
+ {/* Avatar do Assistente */}
118
+ {msg.type === 'assistant' && (
119
+ <div className="flex-shrink-0 pt-1">
120
+ <XerticaOrbe size={32} />
121
+ </div>
122
+ )}
123
+
124
+ <div
125
+ className={cn(
126
+ 'flex flex-col min-w-0 transition-all duration-300',
127
+ msg.type === 'user'
128
+ ? 'max-w-[85%] md:max-w-[70%] items-end w-fit'
129
+ : cn(
130
+ 'items-start',
131
+ msg.tableData || msg.chartData || msg.searchResults || msg.attachmentType === 'document'
132
+ ? 'w-full max-w-full'
133
+ : 'w-fit max-w-[95%] md:max-w-[90%]',
134
+ ),
135
+ )}
136
+ >
137
+ <div
138
+ className={cn(
139
+ 'px-4 py-2 break-words overflow-hidden overflow-x-hidden w-full min-w-0 rounded-2xl',
140
+ msg.type === 'user'
141
+ ? 'bg-primary text-primary-foreground shadow-sm'
142
+ : 'bg-muted text-foreground',
143
+ )}
144
+ >
145
+ {/* Document Header with Edit and Download Buttons */}
146
+ {msg.attachmentType === 'document' && (
147
+ <div className="flex items-center justify-between mb-2 pb-2 border-b border-border min-w-0 overflow-hidden">
148
+ <div className="flex items-center gap-2 min-w-0 flex-1 overflow-hidden">
149
+ <FileText className="w-4 h-4 flex-shrink-0" />
150
+ <span className="text-sm font-medium break-words">{msg.attachmentName}</span>
151
+ </div>
152
+ <div className="flex items-center gap-1 flex-shrink-0">
153
+ <Button
154
+ variant="ghost"
155
+ size="sm"
156
+ onClick={() =>
157
+ msg.documentContent &&
158
+ msg.attachmentName &&
159
+ onDownloadDocument(msg.documentContent, msg.attachmentName)
160
+ }
161
+ className="h-6 px-2"
162
+ title="Baixar"
163
+ >
164
+ <Download className="w-3 h-3" />
165
+ </Button>
166
+ <Button
167
+ variant="ghost"
168
+ size="sm"
169
+ onClick={() =>
170
+ msg.documentContent &&
171
+ msg.documentTitle &&
172
+ onEditDocument(msg.documentContent, msg.documentTitle)
173
+ }
174
+ className="h-6 px-2"
175
+ >
176
+ <Edit className="w-3 h-3 mr-1" />
177
+ Editar
178
+ </Button>
179
+ </div>
180
+ </div>
181
+ )}
182
+
183
+ {/* Attachments (file, audio, image) */}
184
+ {msg.attachmentType &&
185
+ msg.attachmentType !== 'podcast' &&
186
+ msg.attachmentType !== 'document' && (
187
+ <div className="flex items-center gap-2 mb-2 pb-2 border-b border-border min-w-0 overflow-hidden">
188
+ {msg.attachmentType === 'file' && <FileText className="w-4 h-4 flex-shrink-0" />}
189
+ {msg.attachmentType === 'audio' && <Music className="w-4 h-4 flex-shrink-0" />}
190
+ {msg.attachmentType === 'image' && <ImageIcon className="w-4 h-4 flex-shrink-0" />}
191
+ <span className="text-small break-words">{msg.attachmentName}</span>
192
+ </div>
193
+ )}
194
+
195
+ {/* Message Content */}
196
+ {msg.type === 'user' ? (
197
+ <p className="whitespace-pre-wrap break-words">{msg.content}</p>
198
+ ) : (
199
+ <>
200
+ {(msg.content.includes('🔐') || msg.content.includes('❌')) && (
201
+ <div className="mb-3 p-3 border rounded-[var(--radius)] overflow-hidden bg-[var(--toast-error-bg)]/20 border-[var(--toast-error-border)]/30">
202
+ <div className="flex items-start gap-2 min-w-0">
203
+ <AlertCircle className="w-5 h-5 flex-shrink-0 mt-0.5 text-[var(--toast-error-icon)]" />
204
+ <div className="flex-1 min-w-0 overflow-hidden">
205
+ <MarkdownMessage content={msg.content} className="text-foreground" />
206
+ </div>
207
+ </div>
208
+ </div>
209
+ )}
210
+ {!(msg.content.includes('🔐') || msg.content.includes('❌')) && (
211
+ <MarkdownMessage content={msg.content} className="text-foreground" />
212
+ )}
213
+ </>
214
+ )}
215
+
216
+ {/* Chart Rendering */}
217
+ {msg.chartData && msg.chartConfig && (
218
+ <div className="mt-4 w-full h-[300px] min-w-[300px]">
219
+ <ChartContainer config={msg.chartConfig} className="h-full w-full">
220
+ <BarChart accessibilityLayer data={msg.chartData}>
221
+ <CartesianGrid vertical={false} />
222
+ <XAxis
223
+ dataKey="month"
224
+ tickLine={false}
225
+ tickMargin={10}
226
+ axisLine={false}
227
+ tickFormatter={(value) => value.slice(0, 3)}
228
+ />
229
+ <ChartTooltip content={<ChartTooltipContent />} />
230
+ <ChartLegend content={<ChartLegendContent />} />
231
+ {Object.keys(msg.chartConfig).map((key) => (
232
+ <Bar key={key} dataKey={key} fill={`var(--color-${key})`} radius={4} />
233
+ ))}
234
+ </BarChart>
235
+ </ChartContainer>
236
+ </div>
237
+ )}
238
+
239
+ {/* Table Rendering */}
240
+ {msg.tableData && (
241
+ <div className="mt-4 w-full max-w-full border rounded-[var(--radius)] overflow-x-auto custom-scrollbar relative">
242
+ <Table>
243
+ {msg.tableData.caption && <TableCaption>{msg.tableData.caption}</TableCaption>}
244
+ <TableHeader>
245
+ <TableRow>
246
+ {msg.tableData.headers.map((header, i) => (
247
+ <TableHead key={i}>{header}</TableHead>
248
+ ))}
249
+ </TableRow>
250
+ </TableHeader>
251
+ <TableBody>
252
+ {msg.tableData.rows.map((row, i) => (
253
+ <TableRow key={i}>
254
+ {row.map((cell, j) => (
255
+ <TableCell key={j}>{cell}</TableCell>
256
+ ))}
257
+ </TableRow>
258
+ ))}
259
+ </TableBody>
260
+ </Table>
261
+ </div>
262
+ )}
263
+
264
+ {/* Document Preview */}
265
+ {msg.attachmentType === 'document' && msg.documentContent && (
266
+ <div className="mt-3 pt-3 border-t border-border overflow-hidden">
267
+ <FormattedDocument content={msg.documentContent} maxPreviewLength={250} />
268
+ </div>
269
+ )}
270
+
271
+ {/* Podcast Player */}
272
+ {msg.attachmentType === 'podcast' && msg.audioUrl && (
273
+ <div className="mt-3 pt-3 border-t border-border overflow-hidden">
274
+ <div className="flex items-center justify-between mb-3 min-w-0 overflow-hidden">
275
+ <div className="flex items-center gap-2 min-w-0 flex-1 overflow-hidden">
276
+ <div className="w-6 h-6 flex items-center justify-center flex-shrink-0 rounded-[var(--radius-button)] bg-gradient-to-br from-[var(--chart-1)] via-[var(--chart-4)] to-[var(--chart-1)]">
277
+ <Radio className="w-3 h-3 text-white" />
278
+ </div>
279
+ <span className="text-sm font-medium break-words">{msg.attachmentName}</span>
280
+ </div>
281
+ <Button
282
+ variant="ghost"
283
+ size="sm"
284
+ onClick={() =>
285
+ msg.audioUrl &&
286
+ msg.attachmentName &&
287
+ onDownloadPodcast(msg.audioUrl, msg.attachmentName)
288
+ }
289
+ className="h-6 px-2 flex-shrink-0"
290
+ title="Baixar"
291
+ >
292
+ <Download className="w-3 h-3" />
293
+ </Button>
294
+ </div>
295
+ <div className="rounded-[var(--radius)] p-2 overflow-hidden bg-gradient-to-r from-[var(--chart-1)]/10 to-[var(--chart-4)]/10">
296
+ <audio controls className="w-full max-w-full h-10 outline-none">
297
+ <source src={msg.audioUrl} type="audio/mpeg" />
298
+ Seu navegador não suporta o elemento de áudio.
299
+ </audio>
300
+ </div>
301
+ </div>
302
+ )}
303
+
304
+ {/* Search Results */}
305
+ {msg.attachmentType === 'search' && msg.searchResults && (
306
+ <div className="mt-3 pt-3 border-t border-border space-y-4 overflow-hidden">
307
+ <div className="overflow-hidden">
308
+ <div className="flex items-center gap-2 mb-3">
309
+ <Search className="w-4 h-4 text-[var(--chart-4)]" />
310
+ <h4 className="text-foreground">
311
+ Resultados Encontrados ({msg.searchResults.length})
312
+ </h4>
313
+ </div>
314
+ <div className="space-y-2 overflow-hidden">
315
+ {msg.searchResults.map((result) => (
316
+ <div
317
+ key={result.id}
318
+ onClick={() => onOpenSearchResult(result)}
319
+ className="p-3 rounded-[var(--radius)] border border-border transition-all cursor-pointer group overflow-hidden hover:bg-muted/50"
320
+ >
321
+ <div className="flex items-start justify-between gap-2 min-w-0">
322
+ <div className="flex items-start gap-2 flex-1 min-w-0 overflow-hidden">
323
+ <div className="mt-0.5 flex-shrink-0">
324
+ {result.type === 'document' && (
325
+ <FileText className="w-4 h-4 text-[var(--chart-4)]" />
326
+ )}
327
+ {result.type === 'project' && (
328
+ <FolderOpen className="w-4 h-4 text-[var(--chart-1)]" />
329
+ )}
330
+ {result.type === 'conversation' && (
331
+ <MessageSquare className="w-4 h-4 text-[var(--chart-2)]" />
332
+ )}
333
+ {result.type === 'file' && (
334
+ <Folder className="w-4 h-4 text-[var(--chart-3)]" />
335
+ )}
336
+ {result.type === 'contact' && (
337
+ <Users className="w-4 h-4 text-[var(--chart-5)]" />
338
+ )}
339
+ </div>
340
+ <div className="flex-1 min-w-0 overflow-hidden">
341
+ <div className="flex items-start gap-2 min-w-0">
342
+ <h5 className="text-sm font-medium break-words flex-1 min-w-0 text-foreground">
343
+ {result.title}
344
+ </h5>
345
+ <span className="px-1.5 py-0.5 rounded-sm flex-shrink-0 self-start bg-[var(--chart-4)]/10 text-[var(--chart-4)]">
346
+ {result.relevance}%
347
+ </span>
348
+ </div>
349
+ <p className="text-sm text-muted-foreground mt-1 line-clamp-2 break-words">
350
+ {result.description}
351
+ </p>
352
+ <div className="flex items-center gap-3 mt-2 flex-wrap min-w-0">
353
+ <span className="text-sm text-muted-foreground flex items-center gap-1 min-w-0 max-w-full">
354
+ <ExternalLink className="w-3 h-3 flex-shrink-0" />
355
+ <span className="truncate">{result.path}</span>
356
+ </span>
357
+ {result.lastModified && (
358
+ <span className="text-sm text-muted-foreground flex items-center gap-1 flex-shrink-0">
359
+ <Clock className="w-3 h-3" />
360
+ {result.lastModified}
361
+ </span>
362
+ )}
363
+ </div>
364
+ </div>
365
+ </div>
366
+ </div>
367
+ </div>
368
+ ))}
369
+ </div>
370
+ </div>
371
+
372
+ {/* Search Sources */}
373
+ {msg.searchSources && (
374
+ <div>
375
+ <h4 className="mb-2 text-foreground">Fontes Consultadas</h4>
376
+ <div className="flex flex-wrap gap-2 overflow-hidden">
377
+ {msg.searchSources.map((source, index) => (
378
+ <div
379
+ key={index}
380
+ className="px-3 py-1.5 border max-w-full rounded-[var(--radius-button)] bg-muted border-border"
381
+ >
382
+ <span className="text-sm font-medium text-foreground break-words">
383
+ {source.name}
384
+ </span>
385
+ <span className="text-sm text-muted-foreground ml-1 whitespace-nowrap">
386
+ ({source.count})
387
+ </span>
388
+ </div>
389
+ ))}
390
+ </div>
391
+ </div>
392
+ )}
393
+
394
+ {/* Search Commands */}
395
+ {msg.searchCommands && msg.searchResults && (
396
+ <div>
397
+ <h4 className="mb-2 text-foreground">
398
+ O que você pode fazer com estes resultados
399
+ </h4>
400
+ <div className="grid grid-cols-1 gap-2">
401
+ {msg.searchCommands.map((command) => (
402
+ <button
403
+ key={command.id}
404
+ onClick={() =>
405
+ onExecuteSearchCommand(
406
+ command.id,
407
+ msg.content
408
+ .replace('🔍 Pesquisa realizada com sucesso!', '')
409
+ .split('"')[1] || 'pesquisa',
410
+ msg.searchResults!,
411
+ msg.id,
412
+ )
413
+ }
414
+ disabled={executingCommand === command.id}
415
+ className={cn(
416
+ 'flex items-start gap-2 p-2 rounded-[var(--radius)] border transition-all text-left disabled:opacity-50 disabled:cursor-not-allowed',
417
+ savedSearches.includes(msg.id) && command.id === '5'
418
+ ? 'border-[var(--toast-warning-border)] bg-[var(--toast-warning-bg)]/20'
419
+ : 'border-border bg-transparent hover:bg-muted/50',
420
+ )}
421
+ >
422
+ {executingCommand === command.id ? (
423
+ <Loader2 className="w-5 h-5 animate-spin flex-shrink-0 text-primary" />
424
+ ) : (
425
+ <span className="flex-shrink-0">{command.icon}</span>
426
+ )}
427
+ <div className="flex-1 min-w-0 overflow-hidden">
428
+ <div className="text-sm font-medium text-foreground break-words">
429
+ {command.id === '5' && savedSearches.includes(msg.id)
430
+ ? '⭐ Pesquisa salva'
431
+ : command.label}
432
+ </div>
433
+ <div className="text-sm text-muted-foreground break-words">
434
+ {executingCommand === command.id
435
+ ? 'Processando...'
436
+ : command.description}
437
+ </div>
438
+ </div>
439
+ </button>
440
+ ))}
441
+ </div>
442
+ </div>
443
+ )}
444
+ </div>
445
+ )}
446
+ </div>
447
+
448
+ {/* Message Actions */}
449
+ <div className="flex items-center gap-2 mt-1 px-2">
450
+ <span className="text-sm text-muted-foreground">
451
+ {msg.timestamp.toLocaleTimeString('pt-BR', {
452
+ hour: '2-digit',
453
+ minute: '2-digit',
454
+ })}
455
+ </span>
456
+
457
+ {enablePodcastGeneration &&
458
+ msg.type === 'assistant' &&
459
+ msg.attachmentType !== 'podcast' && (
460
+ <Button
461
+ variant="ghost"
462
+ size="sm"
463
+ onClick={() => onGeneratePodcast(msg.id, msg.content)}
464
+ disabled={generatingPodcastId === msg.id}
465
+ className="h-6 w-6 p-0 disabled:opacity-50 text-muted-foreground"
466
+ title="Gerar Podcast"
467
+ aria-label="Gerar Podcast"
468
+ >
469
+ {generatingPodcastId === msg.id ? (
470
+ <Loader2 className="w-3 h-3 animate-spin" />
471
+ ) : (
472
+ <Radio className="w-3 h-3" />
473
+ )}
474
+ </Button>
475
+ )}
476
+
477
+ {msg.type === 'assistant' && (
478
+ <div className="flex items-center gap-1 border-l border-border pl-2 ml-1">
479
+ <Button
480
+ variant="ghost"
481
+ size="icon"
482
+ className={cn(
483
+ 'h-6 w-6 rounded-full hover:bg-green-100 dark:hover:bg-green-900/20 hover:text-green-600',
484
+ msg.evaluation === 'like' &&
485
+ 'text-green-600 bg-green-100 dark:bg-green-900/20',
486
+ )}
487
+ onClick={() => onEvaluationClick(msg.id, 'like')}
488
+ title="Gostei"
489
+ aria-label="Gostei"
490
+ >
491
+ <ThumbsUp className="h-3.5 w-3.5" />
492
+ </Button>
493
+
494
+ <DropdownMenu>
495
+ <DropdownMenuTrigger asChild>
496
+ <Button
497
+ variant="ghost"
498
+ size="icon"
499
+ className={cn(
500
+ 'h-6 w-6 rounded-full hover:bg-red-100 dark:hover:bg-red-900/20 hover:text-red-600',
501
+ msg.evaluation === 'dislike' &&
502
+ 'text-red-600 bg-red-100 dark:bg-red-900/20',
503
+ )}
504
+ title="Não gostei"
505
+ aria-label="Não gostei"
506
+ >
507
+ <ThumbsDown className="h-3.5 w-3.5" />
508
+ </Button>
509
+ </DropdownMenuTrigger>
510
+ <DropdownMenuContent align="start">
511
+ {feedbackOptions && feedbackOptions.length > 0 ? (
512
+ feedbackOptions.map((option, idx) => (
513
+ <DropdownMenuItem
514
+ key={idx}
515
+ onClick={() => onOpenFeedbackDialog(msg.id, option)}
516
+ >
517
+ {option}
518
+ </DropdownMenuItem>
519
+ ))
520
+ ) : (
521
+ <>
522
+ <DropdownMenuItem
523
+ onClick={() =>
524
+ onOpenFeedbackDialog(msg.id, 'Não era o que eu procurava')
525
+ }
526
+ >
527
+ Não era o que eu procurava
528
+ </DropdownMenuItem>
529
+ <DropdownMenuItem
530
+ onClick={() =>
531
+ onOpenFeedbackDialog(msg.id, 'Informação incorreta')
532
+ }
533
+ >
534
+ Informação incorreta
535
+ </DropdownMenuItem>
536
+ <DropdownMenuItem
537
+ onClick={() =>
538
+ onOpenFeedbackDialog(msg.id, 'Resposta incompleta')
539
+ }
540
+ >
541
+ Resposta incompleta
542
+ </DropdownMenuItem>
543
+ </>
544
+ )}
545
+ <DropdownMenuItem onClick={() => onOpenFeedbackDialog(msg.id, null)}>
546
+ Outros...
547
+ </DropdownMenuItem>
548
+ </DropdownMenuContent>
549
+ </DropdownMenu>
550
+ </div>
551
+ )}
552
+
553
+ <Button
554
+ variant="ghost"
555
+ size="sm"
556
+ onClick={() => onCopyMessage(msg.content, msg.id)}
557
+ className={`h-6 w-6 p-0 ${copiedId === msg.id
558
+ ? 'text-[var(--toast-success-icon)]'
559
+ : 'text-muted-foreground'
560
+ }`}
561
+ aria-label={copiedId === msg.id ? 'Copiado' : 'Copiar mensagem'}
562
+ >
563
+ {copiedId === msg.id ? (
564
+ <Check className="w-3 h-3" />
565
+ ) : (
566
+ <Copy className="w-3 h-3" />
567
+ )}
568
+ </Button>
569
+ </div>
570
+ </div>
571
+ </motion.div>
572
+ );
573
+ }
@@ -0,0 +1,65 @@
1
+ import React from 'react';
2
+ import { MessageSquare, Heart, History } from 'lucide-react';
3
+ import { Button } from '../../../ui/button';
4
+ import type { AssistantTab } from '../types';
5
+
6
+ interface AssistantTabBarProps {
7
+ activeTab: AssistantTab;
8
+ showHistory: boolean;
9
+ showFavorites: boolean;
10
+ onTabChange: (tab: AssistantTab) => void;
11
+ }
12
+
13
+ /**
14
+ * AssistantTabBar — Navigation tabs for Chat, History, and Favorites.
15
+ * Only rendered in expanded (non-fullPage) mode when at least one secondary tab is enabled.
16
+ */
17
+ export function AssistantTabBar({
18
+ activeTab,
19
+ showHistory,
20
+ showFavorites,
21
+ onTabChange,
22
+ }: AssistantTabBarProps) {
23
+ return (
24
+ <div className="px-4 py-2 border-b border-border">
25
+ <div className="flex gap-1">
26
+ <Button
27
+ variant={activeTab === 'chat' ? 'default' : 'ghost'}
28
+ size="sm"
29
+ onClick={() => onTabChange('chat')}
30
+ className="flex-1 h-8"
31
+ aria-label="Ver chat"
32
+ >
33
+ <MessageSquare className="w-3 h-3 mr-1" />
34
+ Chat
35
+ </Button>
36
+
37
+ {showHistory && (
38
+ <Button
39
+ variant={activeTab === 'historico' ? 'default' : 'ghost'}
40
+ size="sm"
41
+ onClick={() => onTabChange('historico')}
42
+ className="flex-1 h-8"
43
+ aria-label="Ver histórico de conversas"
44
+ >
45
+ <History className="w-3 h-3 mr-1" />
46
+ Histórico
47
+ </Button>
48
+ )}
49
+
50
+ {showFavorites && (
51
+ <Button
52
+ variant={activeTab === 'favoritos' ? 'default' : 'ghost'}
53
+ size="sm"
54
+ onClick={() => onTabChange('favoritos')}
55
+ className="flex-1 h-8"
56
+ aria-label="Ver mensagens favoritas"
57
+ >
58
+ <Heart className="w-3 h-3 mr-1" />
59
+ Favoritos
60
+ </Button>
61
+ )}
62
+ </div>
63
+ </div>
64
+ );
65
+ }