xertica-ui 2.2.1 → 2.4.0

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 (708) hide show
  1. package/CHANGELOG.md +564 -525
  2. package/README.md +417 -382
  3. package/bin/cli.ts +1244 -748
  4. package/bin/generate-tokens.ts +262 -262
  5. package/bin/language-config.ts +5 -8
  6. package/components/assets/xertica-orbe-animation.ts +1162 -1162
  7. package/components/assistant/code-block/CodeBlock.tsx +268 -268
  8. package/components/assistant/code-block/code-block.stories.tsx +57 -57
  9. package/components/assistant/code-block/code-block.test.tsx +44 -44
  10. package/components/assistant/code-block/index.ts +1 -1
  11. package/components/assistant/formatted-document/FormattedDocument.tsx +147 -147
  12. package/components/assistant/formatted-document/formatted-document.stories.tsx +51 -51
  13. package/components/assistant/formatted-document/formatted-document.test.tsx +42 -42
  14. package/components/assistant/formatted-document/index.ts +1 -1
  15. package/components/assistant/index.ts +6 -6
  16. package/components/assistant/markdown-message/MarkdownMessage.tsx +152 -152
  17. package/components/assistant/markdown-message/index.ts +1 -1
  18. package/components/assistant/markdown-message/markdown-message.stories.tsx +50 -50
  19. package/components/assistant/markdown-message/markdown-message.test.tsx +33 -33
  20. package/components/assistant/modern-chat-input/ModernChatInput.tsx +17 -7
  21. package/components/assistant/modern-chat-input/index.ts +1 -1
  22. package/components/assistant/modern-chat-input/modern-chat-input.stories.tsx +131 -131
  23. package/components/assistant/modern-chat-input/modern-chat-input.test.tsx +79 -79
  24. package/components/assistant/xertica-assistant/index.ts +3 -3
  25. package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +99 -99
  26. package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -106
  27. package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -81
  28. package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +88 -78
  29. package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +75 -75
  30. package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +564 -560
  31. package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +67 -67
  32. package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -41
  33. package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +103 -103
  34. package/components/assistant/xertica-assistant/parts/index.ts +16 -16
  35. package/components/assistant/xertica-assistant/types.ts +134 -134
  36. package/components/assistant/xertica-assistant/use-assistant.ts +615 -615
  37. package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +407 -407
  38. package/components/assistant/xertica-assistant/xertica-assistant.test.tsx +65 -65
  39. package/components/assistant/xertica-assistant/xertica-assistant.tsx +611 -613
  40. package/components/blocks/card-patterns/ActivityCard.tsx +100 -100
  41. package/components/blocks/card-patterns/FeatureCard.tsx +109 -109
  42. package/components/blocks/card-patterns/FeatureCardSkeleton.tsx +1 -6
  43. package/components/blocks/card-patterns/NotificationCard.tsx +140 -140
  44. package/components/blocks/card-patterns/ProfileCard.tsx +112 -114
  45. package/components/blocks/card-patterns/ProjectCard.tsx +123 -123
  46. package/components/blocks/card-patterns/ProjectCardSkeleton.tsx +1 -6
  47. package/components/blocks/card-patterns/QuickActionCard.tsx +68 -68
  48. package/components/blocks/card-patterns/card-patterns.mdx +123 -123
  49. package/components/blocks/card-patterns/card-patterns.stories.tsx +594 -594
  50. package/components/blocks/card-patterns/index.ts +29 -29
  51. package/components/blocks/index.ts +1 -1
  52. package/components/brand/branding/branding.stories.tsx +57 -57
  53. package/components/brand/index.ts +6 -6
  54. package/components/brand/language-selector/index.ts +1 -1
  55. package/components/brand/language-selector/language-selector.mdx +126 -126
  56. package/components/brand/language-selector/language-selector.stories.tsx +1 -4
  57. package/components/brand/theme-toggle/ThemeToggle.tsx +74 -70
  58. package/components/brand/theme-toggle/index.ts +1 -1
  59. package/components/brand/theme-toggle/theme-toggle.stories.tsx +34 -34
  60. package/components/brand/theme-toggle/theme-toggle.test.tsx +34 -34
  61. package/components/brand/xertica-logo/XerticaLogo.stories.tsx +82 -82
  62. package/components/brand/xertica-logo/XerticaLogo.tsx +104 -104
  63. package/components/brand/xertica-logo/index.ts +1 -1
  64. package/components/brand/xertica-logo/xertica-logo.test.tsx +26 -26
  65. package/components/brand/xertica-orbe/XerticaOrbe.tsx +1927 -1927
  66. package/components/brand/xertica-orbe/index.ts +1 -1
  67. package/components/brand/xertica-orbe/xertica-orbe.stories.tsx +40 -40
  68. package/components/brand/xertica-orbe/xertica-orbe.test.tsx +19 -19
  69. package/components/brand/xertica-provider/XerticaProvider.tsx +1 -4
  70. package/components/brand/xertica-provider/index.ts +1 -1
  71. package/components/brand/xertica-provider/xertica-provider.test.tsx +74 -74
  72. package/components/brand/xertica-xlogo/XerticaXLogo.stories.tsx +79 -79
  73. package/components/brand/xertica-xlogo/XerticaXLogo.tsx +65 -65
  74. package/components/brand/xertica-xlogo/index.ts +1 -1
  75. package/components/brand/xertica-xlogo/xertica-xlogo.test.tsx +16 -16
  76. package/components/examples/ApiKeyMapExample.tsx +71 -71
  77. package/components/examples/DrawingMapExample.tsx +565 -565
  78. package/components/examples/FilterableMapExample.tsx +393 -393
  79. package/components/examples/LocationPickerExample.tsx +348 -348
  80. package/components/examples/MapExamples.tsx +268 -268
  81. package/components/examples/MapGmpExample.tsx +169 -169
  82. package/components/examples/MapShowcase.tsx +471 -471
  83. package/components/examples/RouteMapExamples.tsx +329 -329
  84. package/components/examples/SidebarLogoExample.tsx +65 -65
  85. package/components/examples/SimpleFilterableMap.tsx +219 -219
  86. package/components/examples/index.ts +45 -45
  87. package/components/figma/ImageWithFallback.tsx +27 -27
  88. package/components/hooks/index.ts +13 -13
  89. package/components/hooks/use-layout-shortcuts.ts +43 -43
  90. package/components/index.ts +86 -90
  91. package/components/layout/header/header.stories.tsx +204 -204
  92. package/components/layout/header/header.test.tsx +75 -75
  93. package/components/layout/header/header.tsx +349 -349
  94. package/components/layout/header/index.ts +1 -1
  95. package/components/layout/index.ts +2 -2
  96. package/components/layout/sidebar/index.ts +3 -3
  97. package/components/layout/sidebar/sidebar.stories.tsx +586 -586
  98. package/components/layout/sidebar/sidebar.test.tsx +76 -76
  99. package/components/layout/sidebar/sidebar.tsx +1079 -1073
  100. package/components/layout/sidebar/use-sidebar.ts +104 -104
  101. package/components/media/FloatingMediaWrapper.tsx +371 -371
  102. package/components/media/audio-player/AudioPlayer.stories.tsx +124 -124
  103. package/components/media/audio-player/AudioPlayer.test.tsx +106 -106
  104. package/components/media/audio-player/AudioPlayer.tsx +767 -765
  105. package/components/media/audio-player/index.ts +1 -1
  106. package/components/media/audio-player/use-audio-player.ts +312 -312
  107. package/components/media/index.ts +3 -3
  108. package/components/media/video-player/VideoPlayer.stories.tsx +98 -98
  109. package/components/media/video-player/VideoPlayer.test.tsx +73 -73
  110. package/components/media/video-player/VideoPlayer.tsx +310 -310
  111. package/components/media/video-player/index.ts +1 -1
  112. package/components/pages/forgot-password-page/ForgotPasswordPage.stories.tsx +24 -24
  113. package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +188 -188
  114. package/components/pages/forgot-password-page/forgot-password-page.test.tsx +45 -45
  115. package/components/pages/forgot-password-page/index.ts +1 -1
  116. package/components/pages/home-content/HomeContent.stories.tsx +43 -43
  117. package/components/pages/home-content/HomeContent.tsx +120 -120
  118. package/components/pages/home-content/index.ts +1 -1
  119. package/components/pages/home-page/HomePage.stories.tsx +39 -39
  120. package/components/pages/home-page/HomePage.tsx +78 -74
  121. package/components/pages/home-page/home-page.test.tsx +53 -53
  122. package/components/pages/home-page/index.ts +1 -1
  123. package/components/pages/index.ts +8 -8
  124. package/components/pages/login-page/LoginPage.stories.tsx +39 -39
  125. package/components/pages/login-page/LoginPage.tsx +218 -216
  126. package/components/pages/login-page/index.ts +1 -1
  127. package/components/pages/login-page/login-page.test.tsx +63 -63
  128. package/components/pages/reset-password-page/ResetPasswordPage.stories.tsx +24 -24
  129. package/components/pages/reset-password-page/ResetPasswordPage.tsx +243 -239
  130. package/components/pages/reset-password-page/index.ts +1 -1
  131. package/components/pages/template-content/TemplateContent.stories.tsx +43 -43
  132. package/components/pages/template-content/TemplateContent.tsx +1354 -1235
  133. package/components/pages/template-content/index.ts +1 -1
  134. package/components/pages/template-page/TemplatePage.stories.tsx +39 -39
  135. package/components/pages/template-page/TemplatePage.tsx +62 -62
  136. package/components/pages/template-page/index.ts +1 -1
  137. package/components/pages/template-page/template-page.test.tsx +52 -52
  138. package/components/pages/verify-email-page/VerifyEmailPage.stories.tsx +41 -41
  139. package/components/pages/verify-email-page/VerifyEmailPage.tsx +206 -206
  140. package/components/pages/verify-email-page/index.ts +1 -1
  141. package/components/public-api-smoke.test.tsx +52 -52
  142. package/components/shared/CustomTooltipContent.tsx +48 -48
  143. package/components/shared/assistant-utils.test.ts +16 -16
  144. package/components/shared/assistant-utils.ts +225 -225
  145. package/components/shared/error-boundary.stories.tsx +114 -132
  146. package/components/shared/error-boundary.tsx +150 -154
  147. package/components/shared/error-fallbacks.tsx +222 -226
  148. package/components/shared/layout-constants.ts +8 -8
  149. package/components/shared/navigation.ts +35 -35
  150. package/components/shared/use-mobile.test.ts +16 -16
  151. package/components/shared/use-mobile.ts +36 -36
  152. package/components/shared/utils.test.ts +14 -14
  153. package/components/shared/utils.ts +6 -6
  154. package/components/ui/accordion/accordion.stories.tsx +105 -105
  155. package/components/ui/accordion/accordion.test.tsx +59 -59
  156. package/components/ui/accordion/accordion.tsx +77 -77
  157. package/components/ui/accordion/index.ts +1 -1
  158. package/components/ui/alert/alert.stories.tsx +86 -86
  159. package/components/ui/alert/alert.test.tsx +53 -53
  160. package/components/ui/alert/alert.tsx +93 -93
  161. package/components/ui/alert/index.ts +1 -1
  162. package/components/ui/alert-dialog/alert-dialog.stories.tsx +84 -84
  163. package/components/ui/alert-dialog/alert-dialog.test.tsx +70 -70
  164. package/components/ui/alert-dialog/alert-dialog.tsx +149 -149
  165. package/components/ui/alert-dialog/index.ts +1 -1
  166. package/components/ui/aspect-ratio/aspect-ratio.stories.tsx +46 -46
  167. package/components/ui/aspect-ratio/aspect-ratio.test.tsx +28 -28
  168. package/components/ui/aspect-ratio/aspect-ratio.tsx +20 -20
  169. package/components/ui/aspect-ratio/index.ts +1 -1
  170. package/components/ui/assistant-chart/AssistantChart.tsx +64 -64
  171. package/components/ui/assistant-chart/assistant-chart.stories.tsx +44 -44
  172. package/components/ui/assistant-chart/assistant-chart.test.tsx +46 -46
  173. package/components/ui/assistant-chart/index.ts +1 -1
  174. package/components/ui/avatar/avatar.stories.tsx +86 -86
  175. package/components/ui/avatar/avatar.test.tsx +55 -55
  176. package/components/ui/avatar/avatar.tsx +71 -71
  177. package/components/ui/avatar/index.ts +1 -1
  178. package/components/ui/badge/badge.stories.tsx +72 -72
  179. package/components/ui/badge/badge.test.tsx +40 -40
  180. package/components/ui/badge/badge.tsx +58 -58
  181. package/components/ui/badge/index.ts +1 -1
  182. package/components/ui/breadcrumb/breadcrumb.stories.tsx +123 -123
  183. package/components/ui/breadcrumb/breadcrumb.test.tsx +70 -70
  184. package/components/ui/breadcrumb/breadcrumb.tsx +114 -114
  185. package/components/ui/breadcrumb/index.ts +1 -1
  186. package/components/ui/button/button.stories.tsx +183 -183
  187. package/components/ui/button/button.test.tsx +64 -64
  188. package/components/ui/button/button.tsx +98 -98
  189. package/components/ui/button/index.ts +1 -1
  190. package/components/ui/calendar/calendar.stories.tsx +108 -108
  191. package/components/ui/calendar/calendar.test.tsx +53 -53
  192. package/components/ui/calendar/calendar.tsx +230 -230
  193. package/components/ui/calendar/index.ts +1 -1
  194. package/components/ui/card/card.stories.tsx +301 -301
  195. package/components/ui/card/card.test.tsx +55 -55
  196. package/components/ui/card/card.tsx +83 -83
  197. package/components/ui/card/index.ts +1 -1
  198. package/components/ui/carousel/carousel.stories.tsx +80 -80
  199. package/components/ui/carousel/carousel.test.tsx +75 -75
  200. package/components/ui/carousel/carousel.tsx +242 -242
  201. package/components/ui/carousel/index.ts +1 -1
  202. package/components/ui/chart/chart.stories.tsx +1328 -1328
  203. package/components/ui/chart/chart.test.tsx +178 -178
  204. package/components/ui/chart/chart.tsx +2232 -2232
  205. package/components/ui/chart/index.ts +1 -1
  206. package/components/ui/checkbox/checkbox.stories.tsx +109 -109
  207. package/components/ui/checkbox/checkbox.test.tsx +49 -49
  208. package/components/ui/checkbox/checkbox.tsx +68 -68
  209. package/components/ui/checkbox/index.ts +1 -1
  210. package/components/ui/collapsible/collapsible.stories.tsx +45 -45
  211. package/components/ui/collapsible/collapsible.test.tsx +51 -51
  212. package/components/ui/collapsible/collapsible.tsx +32 -32
  213. package/components/ui/collapsible/index.ts +1 -1
  214. package/components/ui/command/command.stories.tsx +134 -134
  215. package/components/ui/command/command.test.tsx +48 -48
  216. package/components/ui/command/command.tsx +163 -163
  217. package/components/ui/command/index.ts +1 -1
  218. package/components/ui/context-menu/context-menu.stories.tsx +76 -76
  219. package/components/ui/context-menu/context-menu.test.tsx +61 -61
  220. package/components/ui/context-menu/context-menu.tsx +236 -236
  221. package/components/ui/context-menu/index.ts +1 -1
  222. package/components/ui/dialog/dialog.stories.tsx +174 -174
  223. package/components/ui/dialog/dialog.test.tsx +78 -78
  224. package/components/ui/dialog/dialog.tsx +189 -189
  225. package/components/ui/dialog/index.ts +1 -1
  226. package/components/ui/drawer/drawer.stories.tsx +71 -71
  227. package/components/ui/drawer/drawer.test.tsx +67 -67
  228. package/components/ui/drawer/drawer.tsx +146 -146
  229. package/components/ui/drawer/index.ts +1 -1
  230. package/components/ui/dropdown-menu/dropdown-menu.stories.tsx +156 -156
  231. package/components/ui/dropdown-menu/dropdown-menu.test.tsx +62 -62
  232. package/components/ui/dropdown-menu/dropdown-menu.tsx +240 -240
  233. package/components/ui/dropdown-menu/index.ts +1 -1
  234. package/components/ui/empty/empty.stories.tsx +85 -85
  235. package/components/ui/empty/empty.test.tsx +31 -31
  236. package/components/ui/empty/empty.tsx +88 -88
  237. package/components/ui/empty/index.ts +1 -1
  238. package/components/ui/file-upload/file-upload.stories.tsx +144 -144
  239. package/components/ui/file-upload/file-upload.test.tsx +65 -65
  240. package/components/ui/file-upload/file-upload.tsx +142 -142
  241. package/components/ui/file-upload/index.ts +2 -2
  242. package/components/ui/file-upload/use-file-upload.ts +177 -177
  243. package/components/ui/form/form.stories.tsx +85 -85
  244. package/components/ui/form/form.test.tsx +75 -75
  245. package/components/ui/form/form.tsx +163 -163
  246. package/components/ui/form/index.ts +1 -1
  247. package/components/ui/google-maps-loader/google-maps-loader.test.tsx +35 -35
  248. package/components/ui/google-maps-loader/google-maps-loader.tsx +465 -465
  249. package/components/ui/google-maps-loader/index.ts +1 -1
  250. package/components/ui/hover-card/hover-card.stories.tsx +61 -61
  251. package/components/ui/hover-card/hover-card.test.tsx +48 -48
  252. package/components/ui/hover-card/hover-card.tsx +50 -50
  253. package/components/ui/hover-card/index.ts +1 -1
  254. package/components/ui/index.ts +400 -400
  255. package/components/ui/input/index.ts +1 -1
  256. package/components/ui/input/input.stories.tsx +153 -153
  257. package/components/ui/input/input.test.tsx +47 -47
  258. package/components/ui/input/input.tsx +57 -57
  259. package/components/ui/input-otp/index.ts +1 -1
  260. package/components/ui/input-otp/input-otp.stories.tsx +120 -120
  261. package/components/ui/input-otp/input-otp.test.tsx +74 -74
  262. package/components/ui/input-otp/input-otp.tsx +101 -101
  263. package/components/ui/label/index.ts +1 -1
  264. package/components/ui/label/label.stories.tsx +74 -74
  265. package/components/ui/label/label.test.tsx +45 -45
  266. package/components/ui/label/label.tsx +53 -53
  267. package/components/ui/map/index.ts +1 -1
  268. package/components/ui/map/map.stories.tsx +86 -86
  269. package/components/ui/map/map.test.tsx +82 -82
  270. package/components/ui/map/map.tsx +506 -506
  271. package/components/ui/map/mock.test.tsx +13 -13
  272. package/components/ui/map-config/index.ts +1 -1
  273. package/components/ui/map-config/map-config.ts +18 -18
  274. package/components/ui/map-layers/index.ts +1 -1
  275. package/components/ui/map-layers/map-layers.test.tsx +48 -48
  276. package/components/ui/map-layers/map-layers.tsx +126 -126
  277. package/components/ui/map.exports/index.ts +1 -1
  278. package/components/ui/map.exports/map.exports.ts +31 -31
  279. package/components/ui/menubar/index.ts +1 -1
  280. package/components/ui/menubar/menubar.stories.tsx +130 -130
  281. package/components/ui/menubar/menubar.test.tsx +53 -53
  282. package/components/ui/menubar/menubar.tsx +265 -265
  283. package/components/ui/navigation-menu/index.ts +1 -1
  284. package/components/ui/navigation-menu/navigation-menu.stories.tsx +126 -126
  285. package/components/ui/navigation-menu/navigation-menu.test.tsx +47 -47
  286. package/components/ui/navigation-menu/navigation-menu.tsx +165 -165
  287. package/components/ui/notification-badge/index.ts +1 -1
  288. package/components/ui/notification-badge/notification-badge.stories.tsx +66 -66
  289. package/components/ui/notification-badge/notification-badge.test.tsx +61 -61
  290. package/components/ui/notification-badge/notification-badge.tsx +91 -91
  291. package/components/ui/page-header/index.ts +1 -1
  292. package/components/ui/page-header/page-header.stories.tsx +69 -69
  293. package/components/ui/page-header/page-header.test.tsx +37 -37
  294. package/components/ui/page-header/page-header.tsx +124 -124
  295. package/components/ui/pagination/index.ts +3 -3
  296. package/components/ui/pagination/pagination.stories.tsx +210 -210
  297. package/components/ui/pagination/pagination.test.tsx +63 -63
  298. package/components/ui/pagination/pagination.tsx +140 -140
  299. package/components/ui/pagination/use-pagination.ts +173 -173
  300. package/components/ui/popover/index.ts +1 -1
  301. package/components/ui/popover/popover.stories.tsx +73 -73
  302. package/components/ui/popover/popover.test.tsx +48 -48
  303. package/components/ui/popover/popover.tsx +54 -54
  304. package/components/ui/progress/index.ts +1 -1
  305. package/components/ui/progress/progress.stories.tsx +55 -55
  306. package/components/ui/progress/progress.test.tsx +23 -23
  307. package/components/ui/progress/progress.tsx +68 -68
  308. package/components/ui/radio-group/index.ts +1 -1
  309. package/components/ui/radio-group/radio-group.stories.tsx +114 -114
  310. package/components/ui/radio-group/radio-group.test.tsx +78 -78
  311. package/components/ui/radio-group/radio-group.tsx +93 -93
  312. package/components/ui/rating/index.ts +1 -1
  313. package/components/ui/rating/rating.stories.tsx +50 -50
  314. package/components/ui/rating/rating.test.tsx +48 -48
  315. package/components/ui/rating/rating.tsx +145 -145
  316. package/components/ui/resizable/index.ts +1 -1
  317. package/components/ui/resizable/resizable.stories.tsx +88 -88
  318. package/components/ui/resizable/resizable.test.tsx +61 -61
  319. package/components/ui/resizable/resizable.tsx +452 -452
  320. package/components/ui/rich-text-editor/index.ts +7 -7
  321. package/components/ui/rich-text-editor/rich-text-editor.stories.tsx +290 -290
  322. package/components/ui/rich-text-editor/rich-text-editor.test.tsx +86 -86
  323. package/components/ui/rich-text-editor/rich-text-editor.tsx +634 -634
  324. package/components/ui/rich-text-editor/use-rich-text-editor.ts +453 -453
  325. package/components/ui/route-map/index.ts +1 -1
  326. package/components/ui/route-map/route-map.stories.tsx +48 -48
  327. package/components/ui/route-map/route-map.test.tsx +108 -108
  328. package/components/ui/route-map/route-map.tsx +349 -349
  329. package/components/ui/scroll-area/index.ts +1 -1
  330. package/components/ui/scroll-area/scroll-area.stories.tsx +31 -31
  331. package/components/ui/scroll-area/scroll-area.test.tsx +27 -27
  332. package/components/ui/scroll-area/scroll-area.tsx +70 -70
  333. package/components/ui/search/index.ts +1 -1
  334. package/components/ui/search/search.stories.tsx +107 -107
  335. package/components/ui/search/search.test.tsx +67 -67
  336. package/components/ui/search/search.tsx +141 -141
  337. package/components/ui/select/index.ts +1 -1
  338. package/components/ui/select/select.stories.tsx +163 -163
  339. package/components/ui/select/select.test.tsx +99 -99
  340. package/components/ui/select/select.tsx +195 -195
  341. package/components/ui/separator/index.ts +1 -1
  342. package/components/ui/separator/separator.stories.tsx +55 -55
  343. package/components/ui/separator/separator.test.tsx +23 -23
  344. package/components/ui/separator/separator.tsx +39 -39
  345. package/components/ui/sheet/index.ts +1 -1
  346. package/components/ui/sheet/sheet.stories.tsx +93 -93
  347. package/components/ui/sheet/sheet.test.tsx +62 -62
  348. package/components/ui/sheet/sheet.tsx +149 -149
  349. package/components/ui/simple-map/index.ts +1 -1
  350. package/components/ui/simple-map/simple-map.stories.tsx +44 -44
  351. package/components/ui/simple-map/simple-map.test.tsx +36 -36
  352. package/components/ui/simple-map/simple-map.tsx +92 -92
  353. package/components/ui/skeleton/index.ts +1 -1
  354. package/components/ui/skeleton/skeleton.stories.tsx +36 -36
  355. package/components/ui/skeleton/skeleton.test.tsx +19 -19
  356. package/components/ui/skeleton/skeleton.tsx +25 -25
  357. package/components/ui/slider/index.ts +1 -1
  358. package/components/ui/slider/slider.stories.tsx +44 -44
  359. package/components/ui/slider/slider.test.tsx +25 -25
  360. package/components/ui/slider/slider.tsx +66 -66
  361. package/components/ui/sonner/index.ts +1 -1
  362. package/components/ui/sonner/sonner.stories.tsx +41 -41
  363. package/components/ui/sonner/sonner.test.tsx +24 -24
  364. package/components/ui/sonner/sonner.tsx +74 -74
  365. package/components/ui/stats-card/index.ts +2 -2
  366. package/components/ui/stats-card/stats-card-skeleton.tsx +1 -3
  367. package/components/ui/stats-card/stats-card.stories.tsx +99 -99
  368. package/components/ui/stats-card/stats-card.test.tsx +34 -34
  369. package/components/ui/stats-card/stats-card.tsx +93 -93
  370. package/components/ui/stepper/index.ts +3 -3
  371. package/components/ui/stepper/stepper.stories.tsx +171 -171
  372. package/components/ui/stepper/stepper.test.tsx +47 -47
  373. package/components/ui/stepper/stepper.tsx +190 -190
  374. package/components/ui/stepper/use-stepper.ts +139 -139
  375. package/components/ui/switch/index.ts +1 -1
  376. package/components/ui/switch/switch.stories.tsx +93 -93
  377. package/components/ui/switch/switch.test.tsx +44 -44
  378. package/components/ui/switch/switch.tsx +70 -70
  379. package/components/ui/table/index.ts +1 -1
  380. package/components/ui/table/table.stories.tsx +114 -114
  381. package/components/ui/table/table.test.tsx +43 -43
  382. package/components/ui/table/table.tsx +104 -104
  383. package/components/ui/tabs/index.ts +1 -1
  384. package/components/ui/tabs/tabs.stories.tsx +140 -140
  385. package/components/ui/tabs/tabs.test.tsx +50 -50
  386. package/components/ui/tabs/tabs.tsx +66 -66
  387. package/components/ui/textarea/index.ts +1 -1
  388. package/components/ui/textarea/textarea.stories.tsx +69 -69
  389. package/components/ui/textarea/textarea.test.tsx +41 -41
  390. package/components/ui/textarea/textarea.tsx +61 -61
  391. package/components/ui/timeline/index.ts +1 -1
  392. package/components/ui/timeline/timeline.stories.tsx +97 -97
  393. package/components/ui/timeline/timeline.test.tsx +53 -53
  394. package/components/ui/timeline/timeline.tsx +124 -124
  395. package/components/ui/toggle/index.ts +1 -1
  396. package/components/ui/toggle/toggle.stories.tsx +56 -56
  397. package/components/ui/toggle/toggle.test.tsx +32 -32
  398. package/components/ui/toggle/toggle.tsx +55 -55
  399. package/components/ui/toggle-group/index.ts +1 -1
  400. package/components/ui/toggle-group/toggle-group.stories.tsx +66 -66
  401. package/components/ui/toggle-group/toggle-group.test.tsx +47 -47
  402. package/components/ui/toggle-group/toggle-group.tsx +79 -79
  403. package/components/ui/tooltip/index.ts +1 -1
  404. package/components/ui/tooltip/tooltip.stories.tsx +83 -83
  405. package/components/ui/tooltip/tooltip.test.tsx +39 -39
  406. package/components/ui/tooltip/tooltip.tsx +69 -69
  407. package/components/ui/tree-view/index.ts +4 -4
  408. package/components/ui/tree-view/tree-view.stories.tsx +154 -154
  409. package/components/ui/tree-view/tree-view.test.tsx +58 -58
  410. package/components/ui/tree-view/tree-view.tsx +171 -171
  411. package/components/ui/tree-view/use-tree-view.ts +237 -237
  412. package/components.json +892 -892
  413. package/contexts/ApiKeyContext.test.tsx +26 -26
  414. package/contexts/ApiKeyContext.tsx +196 -196
  415. package/contexts/AssistenteContext.test.tsx +17 -17
  416. package/contexts/AssistenteContext.tsx +113 -113
  417. package/contexts/AuthContext.tsx +121 -118
  418. package/contexts/BrandColorsContext.test.tsx +21 -21
  419. package/contexts/BrandColorsContext.tsx +251 -251
  420. package/contexts/LanguageContext.tsx +1 -2
  421. package/contexts/LayoutContext.test.tsx +29 -29
  422. package/contexts/LayoutContext.tsx +140 -140
  423. package/contexts/ThemeContext.test.tsx +38 -38
  424. package/contexts/ThemeContext.tsx +111 -111
  425. package/contexts/index.ts +8 -8
  426. package/contexts/theme-data.ts +340 -340
  427. package/dist/AssistantChart-COGiOV-g.cjs +3541 -0
  428. package/dist/AssistantChart-CWX1OWNM.js +3373 -0
  429. package/dist/AudioPlayer-9psiEucT.cjs +1282 -0
  430. package/dist/AudioPlayer-Dp2bD1Gk.js +1278 -0
  431. package/dist/BrandColorsContext-DZT7JjeD.js +659 -0
  432. package/dist/BrandColorsContext-awnBCmC4.cjs +666 -0
  433. package/dist/CodeBlock-DYkTfR0f.js +221 -0
  434. package/dist/CodeBlock-EOvp9cVu.cjs +223 -0
  435. package/dist/CustomTooltipContent-BhdIeBEg.cjs +54 -0
  436. package/dist/CustomTooltipContent-CNbVB2NS.js +33 -0
  437. package/dist/FeatureCard-BZ4CYxFf.cjs +497 -0
  438. package/dist/FeatureCard-DNycVGwT.js +485 -0
  439. package/dist/FeatureCardSkeleton-DZqc96mt.js +27 -0
  440. package/dist/FeatureCardSkeleton-pTa0YNKP.cjs +29 -0
  441. package/dist/LayoutContext-BEq_-n98.cjs +96 -0
  442. package/dist/LayoutContext-DNl1xSoX.js +92 -0
  443. package/dist/ThemeContext-CMD3z2Dz.cjs +1930 -0
  444. package/dist/ThemeContext-x_F2zsnv.js +1923 -0
  445. package/dist/VerifyEmailPage-BJjAMUTW.js +3223 -0
  446. package/dist/VerifyEmailPage-Bv8Ah_TK.cjs +3235 -0
  447. package/dist/VerifyEmailPage-CkBYfsNy.cjs +3232 -0
  448. package/dist/VerifyEmailPage-Cyl55sJb.js +3226 -0
  449. package/dist/VerifyEmailPage-X14vhdyl.js +3296 -0
  450. package/dist/VerifyEmailPage-u_Dn7t1U.cjs +3305 -0
  451. package/dist/XerticaOrbe-Uk2JML1-.cjs +1927 -0
  452. package/dist/XerticaOrbe-jA5T2iOk.js +1925 -0
  453. package/dist/XerticaProvider-BErr83Bg.js +42 -0
  454. package/dist/XerticaProvider-CwOkHxiT.cjs +44 -0
  455. package/dist/XerticaProvider-DUOJg9iX.js +49 -0
  456. package/dist/XerticaProvider-Dl_b72_l.cjs +51 -0
  457. package/dist/XerticaXLogo-BX3ueACh.js +255 -0
  458. package/dist/XerticaXLogo-mqjoBiLI.js +252 -0
  459. package/dist/XerticaXLogo-qBPhwK3g.cjs +260 -0
  460. package/dist/XerticaXLogo-uQgwns_E.cjs +257 -0
  461. package/dist/alert-dialog-DhwPioBa.cjs +885 -0
  462. package/dist/alert-dialog-DqlRW_An.js +831 -0
  463. package/dist/assistant.cjs.js +8 -4
  464. package/dist/assistant.es.js +5 -11
  465. package/dist/avatar-3kO2Anrp.js +54 -0
  466. package/dist/avatar-BCM7YQRC.cjs +77 -0
  467. package/dist/blocks.cjs.js +9 -4
  468. package/dist/blocks.es.js +2 -16
  469. package/dist/brand.cjs.js +10 -5
  470. package/dist/brand.es.js +3 -11
  471. package/dist/breadcrumb-BKtHF4gk.cjs +98 -0
  472. package/dist/breadcrumb-ifNsA7Zl.js +90 -0
  473. package/dist/button-0BlA47It.cjs +85 -0
  474. package/dist/button-DZHzN1Gd.js +62 -0
  475. package/dist/cli.js +471 -93
  476. package/dist/components/brand/theme-toggle/ThemeToggle.d.ts +1 -1
  477. package/dist/components/index.d.ts +1 -1
  478. package/dist/dropdown-menu-BMcykFDf.cjs +225 -0
  479. package/dist/dropdown-menu-Dn_eV2Xb.js +190 -0
  480. package/dist/google-maps-loader-BCe58h9D.js +308 -0
  481. package/dist/google-maps-loader-casMyxlo.cjs +316 -0
  482. package/dist/hooks.cjs.js +12 -8
  483. package/dist/hooks.es.js +10 -27
  484. package/dist/index-9GWd0qxq.cjs +12 -0
  485. package/dist/index-BabBx2pa.js +6 -0
  486. package/dist/index.cjs.js +37 -32
  487. package/dist/index.es.js +30 -363
  488. package/dist/input-C_UiS2Py.cjs +152 -0
  489. package/dist/input-cc-PTD4R.js +123 -0
  490. package/dist/layout.cjs.js +10 -6
  491. package/dist/layout.es.js +7 -9
  492. package/dist/media.cjs.js +8 -3
  493. package/dist/media.es.js +1 -6
  494. package/dist/pages.cjs.js +8 -3
  495. package/dist/pages.es.js +1 -11
  496. package/dist/progress-C7Lti5wo.js +80 -0
  497. package/dist/progress-Cqwxbqs1.cjs +103 -0
  498. package/dist/rich-text-editor-DqLICivI.js +2832 -0
  499. package/dist/rich-text-editor-DxO1Hz3a.cjs +2903 -0
  500. package/dist/select-CH6v_KcQ.cjs +161 -0
  501. package/dist/select-D-xvCZK2.js +130 -0
  502. package/dist/sidebar-3XyzjVBw.js +792 -0
  503. package/dist/sidebar-B4ZWaMrE.js +792 -0
  504. package/dist/sidebar-BS1p2V7t.cjs +795 -0
  505. package/dist/sidebar-DyYvgyBj.cjs +795 -0
  506. package/dist/skeleton-DjiHerJn.cjs +87 -0
  507. package/dist/skeleton-DtR5tkYe.js +78 -0
  508. package/dist/slider-B00b9SVK.cjs +78 -0
  509. package/dist/slider-DQCNUUMj.js +56 -0
  510. package/dist/sonner-B-jWlik1.cjs +68 -0
  511. package/dist/sonner-C9tiqj4f.js +47 -0
  512. package/dist/tooltip-D8n9UYoU.cjs +72 -0
  513. package/dist/tooltip-RtbSmPYJ.js +48 -0
  514. package/dist/ui.cjs.js +23 -18
  515. package/dist/ui.es.js +16 -303
  516. package/dist/use-audio-player-B78fd2ct.js +188 -0
  517. package/dist/use-audio-player-DGvhPrgR.cjs +190 -0
  518. package/dist/use-mobile-BdXTRb0Z.cjs +51 -0
  519. package/dist/use-mobile-Ce2cBAQe.js +29 -0
  520. package/dist/xertica-assistant-B1NaSFFj.js +2173 -0
  521. package/dist/xertica-assistant-B687qEPU.js +2165 -0
  522. package/dist/xertica-assistant-CIaUlbIt.cjs +2180 -0
  523. package/dist/xertica-assistant-sOHwTgIP.cjs +2172 -0
  524. package/dist/xertica-ui.css +1 -1
  525. package/docs/ai-usage.md +195 -195
  526. package/docs/architecture-improvements.md +456 -456
  527. package/docs/architecture.md +312 -306
  528. package/docs/components/accordion.md +109 -109
  529. package/docs/components/alert-dialog.md +127 -127
  530. package/docs/components/alert.md +106 -106
  531. package/docs/components/aspect-ratio.md +58 -58
  532. package/docs/components/assistant-chart.md +47 -47
  533. package/docs/components/assistant.md +428 -426
  534. package/docs/components/audio-player.md +167 -167
  535. package/docs/components/avatar.md +101 -101
  536. package/docs/components/badge.md +84 -84
  537. package/docs/components/branding.md +252 -252
  538. package/docs/components/breadcrumb.md +104 -104
  539. package/docs/components/button.md +156 -156
  540. package/docs/components/calendar.md +141 -141
  541. package/docs/components/card-patterns.md +447 -445
  542. package/docs/components/card.md +245 -245
  543. package/docs/components/carousel.md +100 -100
  544. package/docs/components/chart.md +638 -638
  545. package/docs/components/checkbox.md +88 -88
  546. package/docs/components/code-block.md +105 -105
  547. package/docs/components/collapsible.md +86 -86
  548. package/docs/components/command.md +113 -113
  549. package/docs/components/context-menu.md +81 -81
  550. package/docs/components/dialog.md +198 -198
  551. package/docs/components/drawer.md +105 -105
  552. package/docs/components/dropdown-menu.md +127 -127
  553. package/docs/components/empty.md +127 -127
  554. package/docs/components/error-boundary.md +201 -191
  555. package/docs/components/file-upload.md +189 -189
  556. package/docs/components/floating-media-wrapper.md +63 -63
  557. package/docs/components/form.md +177 -177
  558. package/docs/components/formatted-document.md +105 -105
  559. package/docs/components/google-maps-loader.md +44 -44
  560. package/docs/components/header.md +177 -177
  561. package/docs/components/hooks.md +432 -430
  562. package/docs/components/hover-card.md +86 -86
  563. package/docs/components/image-with-fallback.md +107 -107
  564. package/docs/components/input-otp.md +95 -95
  565. package/docs/components/input.md +130 -130
  566. package/docs/components/label.md +69 -69
  567. package/docs/components/language-selector.md +20 -16
  568. package/docs/components/map-layers.md +138 -138
  569. package/docs/components/map.md +84 -84
  570. package/docs/components/markdown-message.md +47 -47
  571. package/docs/components/menubar.md +89 -89
  572. package/docs/components/modern-chat-input.md +164 -164
  573. package/docs/components/navigation-menu.md +83 -83
  574. package/docs/components/notification-badge.md +78 -78
  575. package/docs/components/page-header.md +93 -93
  576. package/docs/components/pages.md +323 -309
  577. package/docs/components/pagination.md +334 -334
  578. package/docs/components/popover.md +116 -116
  579. package/docs/components/progress.md +103 -103
  580. package/docs/components/radio-group.md +133 -133
  581. package/docs/components/rating.md +77 -77
  582. package/docs/components/resizable.md +84 -84
  583. package/docs/components/rich-text-editor.md +255 -255
  584. package/docs/components/route-map.md +124 -124
  585. package/docs/components/scroll-area.md +58 -58
  586. package/docs/components/search.md +87 -87
  587. package/docs/components/select.md +144 -144
  588. package/docs/components/separator.md +58 -58
  589. package/docs/components/sheet.md +122 -122
  590. package/docs/components/sidebar.md +314 -314
  591. package/docs/components/simple-map.md +51 -51
  592. package/docs/components/skeleton.md +99 -99
  593. package/docs/components/slider.md +84 -84
  594. package/docs/components/sonner.md +115 -115
  595. package/docs/components/stats-card.md +120 -120
  596. package/docs/components/stepper.md +268 -268
  597. package/docs/components/switch.md +106 -106
  598. package/docs/components/table.md +138 -138
  599. package/docs/components/tabs.md +117 -117
  600. package/docs/components/textarea.md +86 -86
  601. package/docs/components/theme-toggle.md +73 -73
  602. package/docs/components/timeline.md +121 -121
  603. package/docs/components/toggle-group.md +68 -68
  604. package/docs/components/toggle.md +62 -62
  605. package/docs/components/tooltip.md +116 -116
  606. package/docs/components/tree-view.md +238 -238
  607. package/docs/components/use-mobile.md +96 -96
  608. package/docs/components/video-player.md +68 -68
  609. package/docs/components/xertica-logo.md +36 -36
  610. package/docs/components/xertica-orbe.md +35 -35
  611. package/docs/components/xertica-provider.md +65 -65
  612. package/docs/components/xertica-xlogo.md +35 -35
  613. package/docs/decision-tree.md +293 -293
  614. package/docs/doc-audit.md +244 -243
  615. package/docs/form-sizing.md +162 -162
  616. package/docs/getting-started.md +616 -591
  617. package/docs/guidelines.md +330 -328
  618. package/docs/i18n.md +61 -57
  619. package/docs/installation.md +268 -267
  620. package/docs/layout.md +143 -143
  621. package/docs/llms.md +295 -295
  622. package/docs/patterns/analytics.md +194 -194
  623. package/docs/patterns/crud.md +149 -149
  624. package/docs/patterns/dashboard.md +138 -138
  625. package/docs/patterns/detail-page.md +296 -296
  626. package/docs/patterns/form.md +241 -241
  627. package/docs/patterns/login.md +156 -156
  628. package/docs/patterns/settings.md +368 -368
  629. package/docs/patterns/wizard.md +213 -213
  630. package/docs/state-management.md +289 -289
  631. package/guidelines/Guidelines.md +409 -406
  632. package/hooks/useTheme.test.tsx +16 -16
  633. package/hooks/useTheme.ts +4 -4
  634. package/imports/Podcast.tsx +540 -540
  635. package/imports/XerticaAi.tsx +46 -46
  636. package/imports/XerticaX.tsx +15 -15
  637. package/imports/svg-aueiaqngck.ts +20 -20
  638. package/imports/svg-v9krss1ozd.ts +23 -23
  639. package/imports/svg-vhrdofe3qe.ts +6 -6
  640. package/llms-compact.txt +2 -1
  641. package/llms.txt +2 -1
  642. package/mcp/resources.json +22 -22
  643. package/mcp/tools.json +35 -35
  644. package/package.json +219 -213
  645. package/scripts/ai-validator.ts +91 -91
  646. package/scripts/cleanup-case-dupes.ts +62 -62
  647. package/scripts/generate-ai-manifests.ts +107 -107
  648. package/styles/globals.css +13 -13
  649. package/styles/xertica/app-overrides/chat.css +61 -61
  650. package/styles/xertica/app-overrides/scrollbar.css +33 -33
  651. package/styles/xertica/base.css +90 -71
  652. package/styles/xertica/integrations/google-maps.css +76 -76
  653. package/styles/xertica/integrations/sonner.css +73 -73
  654. package/styles/xertica/theme-map.css +102 -99
  655. package/styles/xertica/tokens.css +240 -236
  656. package/templates/CLAUDE.md +16 -1
  657. package/templates/eslint.config.js +26 -26
  658. package/templates/guidelines/Guidelines.md +577 -553
  659. package/templates/package.json +69 -69
  660. package/templates/postcss.config.js +6 -6
  661. package/templates/src/app/App.tsx +46 -46
  662. package/templates/src/app/components/AppLayout.tsx +55 -55
  663. package/templates/src/app/components/AuthGuard.tsx +131 -82
  664. package/templates/src/app/context/AuthContext.tsx +108 -108
  665. package/templates/src/features/assistant/index.ts +5 -5
  666. package/templates/src/features/auth/index.ts +4 -4
  667. package/templates/src/features/auth/ui/AuthPageShell.tsx +32 -32
  668. package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -72
  669. package/templates/src/features/auth/ui/LoginContent.tsx +92 -92
  670. package/templates/src/features/auth/ui/ResetPasswordContent.tsx +6 -2
  671. package/templates/src/features/auth/ui/SocialLoginButtons.tsx +78 -78
  672. package/templates/src/features/auth/ui/VerifyEmailContent.tsx +2 -6
  673. package/templates/src/features/home/data/mock.ts +41 -35
  674. package/templates/src/features/home/index.ts +11 -11
  675. package/templates/src/features/home/store/dashboardStore.ts +25 -25
  676. package/templates/src/features/home/ui/HomeContent.tsx +117 -119
  677. package/templates/src/features/template/index.ts +5 -5
  678. package/templates/src/features/template/ui/CrudTemplate.tsx +1 -4
  679. package/templates/src/features/template/ui/LoginTemplate.tsx +1 -1
  680. package/templates/src/features/template/ui/TemplateContent.tsx +29 -21
  681. package/templates/src/locales/en/pages/templates.json +17 -17
  682. package/templates/src/locales/es/pages/templates.json +17 -17
  683. package/templates/src/locales/pt-BR/pages/templates.json +17 -17
  684. package/templates/src/main.tsx +11 -11
  685. package/templates/src/pages/AssistantPage.tsx +26 -20
  686. package/templates/src/pages/ForgotPasswordPage.tsx +6 -6
  687. package/templates/src/pages/HomePage.tsx +53 -49
  688. package/templates/src/pages/LoginPage.tsx +10 -10
  689. package/templates/src/pages/ResetPasswordPage.tsx +6 -6
  690. package/templates/src/pages/TemplatePage.tsx +28 -28
  691. package/templates/src/pages/VerifyEmailPage.tsx +6 -6
  692. package/templates/src/shared/config/navigation.ts +19 -19
  693. package/templates/src/shared/error-boundary.tsx +150 -154
  694. package/templates/src/shared/error-fallbacks.tsx +222 -226
  695. package/templates/src/shared/lib/auth.ts +20 -20
  696. package/templates/src/shared/types/auth.ts +3 -3
  697. package/templates/src/styles/index.css +95 -95
  698. package/templates/src/styles/xertica/tokens.css +240 -236
  699. package/templates/tsconfig.json +25 -25
  700. package/templates/tsconfig.node.json +12 -12
  701. package/templates/vite-env.d.ts +1 -1
  702. package/templates/vite.config.js +20 -20
  703. package/templates/vite.config.ts +54 -51
  704. package/utils/color-utils.ts +72 -72
  705. package/utils/demo-responses.test.ts +10 -10
  706. package/utils/demo-responses.ts +151 -151
  707. package/utils/gemini.test.ts +25 -25
  708. package/utils/gemini.ts +155 -155
@@ -0,0 +1,2180 @@
1
+ 'use strict';
2
+
3
+ const jsxRuntime = require('react/jsx-runtime');
4
+ const React = require('react');
5
+ const reactI18next = require('react-i18next');
6
+ const sonner = require('sonner');
7
+ const lucideReact = require('lucide-react');
8
+ const useMobile = require('./use-mobile-BdXTRb0Z.cjs');
9
+ const framerMotion = require('framer-motion');
10
+ const input = require('./input-C_UiS2Py.cjs');
11
+ const button = require('./button-0BlA47It.cjs');
12
+ const XerticaOrbe = require('./XerticaOrbe-Uk2JML1-.cjs');
13
+ const tooltip = require('./tooltip-D8n9UYoU.cjs');
14
+ const CustomTooltipContent = require('./CustomTooltipContent-BhdIeBEg.cjs');
15
+ const RechartsPrimitive = require('recharts');
16
+ const richTextEditor = require('./rich-text-editor-DxO1Hz3a.cjs');
17
+ const dropdownMenu = require('./dropdown-menu-BMcykFDf.cjs');
18
+
19
+ [
20
+ {
21
+ id: "rich-1",
22
+ text: "Ver exemplo de Gráfico",
23
+ icon: React.createElement(lucideReact.BarChart3, { className: "w-4 h-4 mr-2" })
24
+ },
25
+ {
26
+ id: "rich-2",
27
+ text: "Ver exemplo de Imagem",
28
+ icon: React.createElement(lucideReact.ImageIcon, { className: "w-4 h-4 mr-2" })
29
+ },
30
+ {
31
+ id: "rich-3",
32
+ text: "Ver exemplo de Tabela",
33
+ icon: React.createElement(lucideReact.Table, { className: "w-4 h-4 mr-2" })
34
+ },
35
+ {
36
+ id: "rich-4",
37
+ text: "Ver exemplo de Documento",
38
+ icon: React.createElement(lucideReact.FileText, { className: "w-4 h-4 mr-2" })
39
+ }
40
+ ];
41
+ const gerarResposta = (mensagemUsuario, customResponses) => {
42
+ const mensagemLower = mensagemUsuario.toLowerCase();
43
+ if (customResponses && customResponses.length > 0) {
44
+ for (const mock of customResponses) {
45
+ const trigger = mock.trigger;
46
+ let match = false;
47
+ if (trigger instanceof RegExp) {
48
+ match = trigger.test(mensagemUsuario);
49
+ } else {
50
+ match = mensagemLower.includes(trigger.toLowerCase());
51
+ }
52
+ if (match) {
53
+ return mock.response;
54
+ }
55
+ }
56
+ }
57
+ const mensagemOriginal = mensagemUsuario;
58
+ if (mensagemLower.includes("o que") && (mensagemLower.includes("fazer") || mensagemLower.includes("pedir"))) {
59
+ return "Posso ajudar você com diversas tarefas! Posso:\n\n• Analisar dados e métricas dos seus projetos\n• Responder perguntas sobre performance e resultados\n• Sugerir otimizações e melhorias\n• Gerar relatórios e documentação\n• Ajudar no planejamento de sprints\n• E muito mais!\n\nQual tarefa você gostaria de realizar primeiro?";
60
+ }
61
+ if (mensagemLower.includes("o que você faz") || mensagemLower.includes("quem é você")) {
62
+ return "Olá! Sou o Assistente Xertica, uma IA desenvolvida para ajudar você a gerenciar projetos, analisar dados e otimizar processos. Estou aqui 24/7 para responder suas perguntas e auxiliar nas suas tarefas diárias.\n\nPosso processar documentos, analisar áudios e imagens, além de fornecer insights baseados nos dados da plataforma.";
63
+ }
64
+ if (mensagemLower.includes("projeto") && (mensagemLower.includes("preocupar") || mensagemLower.includes("atenção"))) {
65
+ return "Com base na análise dos seus projetos ativos, recomendo focar nos seguintes:\n\n1. **Projeto Alpha** - 15% acima do prazo, requer atenção imediata\n2. **Sistema Beta** - Performance crítica, necessita otimização\n3. **Mobile Gamma** - Aguardando aprovações há 5 dias\n\nGostaria de mais detalhes sobre algum deles?";
66
+ }
67
+ if (mensagemLower.includes("próximo projeto") || mensagemLower.includes("próxima tarefa")) {
68
+ return "Seu próximo projeto prioritário é o **Sistema de Analytics V2**.\n\n📅 Início previsto: Próxima segunda-feira\n👥 Time: 5 desenvolvedores\n⏱️ Duração estimada: 3 sprints\n\nJá preparei um roadmap inicial. Gostaria de revisar?";
69
+ }
70
+ if (mensagemLower.includes("desempenho") || mensagemLower.includes("performance") || mensagemLower.includes("melhor")) {
71
+ return "Analisando os dados de performance dos últimos 30 dias:\n\n🏆 **Melhor Performance:**\n• Projeto Dashboard 2.0: +35% eficiência\n• Sistema CRM: -40% tempo de resposta\n• App Mobile: 4.8★ rating (+0.5)\n\n📊 Todos estão acima das metas estabelecidas. Parabéns!\n\nQuer ver métricas detalhadas?";
72
+ }
73
+ if (mensagemLower.includes("olá") || mensagemLower.includes("oi") || mensagemLower.includes("bom dia") || mensagemLower.includes("boa tarde") || mensagemLower.includes("boa noite")) {
74
+ return "Olá! 👋 Como posso ajudar você hoje? Estou pronto para auxiliar com análises, relatórios ou responder suas dúvidas sobre os projetos.";
75
+ }
76
+ if (mensagemLower.includes("obrigado") || mensagemLower.includes("obrigada")) {
77
+ return "Por nada! Estou aqui sempre que precisar. 😊 Se tiver mais alguma dúvida ou precisar de ajuda, é só chamar!";
78
+ }
79
+ if (mensagemLower.includes("criar documento")) {
80
+ const tema = mensagemOriginal.replace(/📄 \[Criar documento\]/gi, "").trim() || "Novo Documento";
81
+ return {
82
+ content: `📝 Documento criado com sucesso!
83
+
84
+ Gerei um documento completo sobre "${tema}". O documento está pronto para revisão e pode ser editado conforme necessário.`,
85
+ attachmentType: "document",
86
+ attachmentName: `Documento - ${tema}.md`,
87
+ documentTitle: tema,
88
+ documentContent: `# ${tema}
89
+
90
+ ## Introdução
91
+ Este é um documento gerado automaticamente sobre ${tema}.
92
+
93
+ ## Detalhes
94
+ - Item 1
95
+ - Item 2
96
+
97
+ ## Conclusão
98
+ Documento finalizado.`
99
+ };
100
+ }
101
+ if (mensagemLower.includes("gráfico") || mensagemLower.includes("chart")) {
102
+ return {
103
+ content: "Aqui está a análise de performance solicitada:",
104
+ chartData: [
105
+ { month: "Jan", desktop: 186, mobile: 80 },
106
+ { month: "Fev", desktop: 305, mobile: 200 },
107
+ { month: "Mar", desktop: 237, mobile: 120 },
108
+ { month: "Abr", desktop: 73, mobile: 190 },
109
+ { month: "Mai", desktop: 209, mobile: 130 },
110
+ { month: "Jun", desktop: 214, mobile: 140 }
111
+ ],
112
+ chartConfig: {
113
+ desktop: { label: "Desktop", color: "hsl(var(--primary))" },
114
+ mobile: { label: "Mobile", color: "hsl(var(--destructive))" }
115
+ }
116
+ };
117
+ }
118
+ if (mensagemLower.includes("tabela") || mensagemLower.includes("table")) {
119
+ return {
120
+ content: "Aqui estão os dados estruturados conforme solicitado:",
121
+ tableData: {
122
+ caption: "Lista de Projetos Ativos",
123
+ headers: ["Projeto", "Status", "Prazo"],
124
+ rows: [
125
+ ["Alpha", "Em andamento", "15/05"],
126
+ ["Beta", "Concluido", "02/04"],
127
+ ["Gamma", "Atrasado", "10/01"]
128
+ ]
129
+ }
130
+ };
131
+ }
132
+ if (mensagemLower.includes("exemplo de documento")) {
133
+ return {
134
+ content: "Com certeza! Aqui está um exemplo de documento profissional que acabei de gerar:",
135
+ attachmentType: "document",
136
+ attachmentName: "Proposta_Comercial_Xertica.md",
137
+ documentTitle: "Proposta Comercial Xertica",
138
+ documentContent: "# Proposta Comercial\n\n## 1. Visão Geral\nNossa solução oferece o melhor desempenho para sua empresa.\n\n## 2. Investimento\nO valor total é de R$ 50.000,00."
139
+ };
140
+ }
141
+ if (mensagemLower.includes("arquivo") || mensagemLower.includes("documento")) {
142
+ return "Entendi que você deseja trabalhar com arquivos. Posso analisar diversos tipos de documentos:\n\n📄 Documentos de texto (PDF, DOCX)\n📊 Planilhas (XLSX, CSV)\n📈 Relatórios e apresentações\n\nBasta enviá-los usando o botão de anexo (📎) e terei prazer em analisá-los para você!";
143
+ }
144
+ const respostasGenericas = [
145
+ "Entendo sua questão. Com base nos dados disponíveis na plataforma Xertica, posso fornecer análises detalhadas sobre esse tema. Poderia me dar mais contexto para que eu possa ajudá-lo melhor?",
146
+ "Interessante! Deixe-me processar isso... Com base no seu histórico e nos dados do sistema, recomendo que possamos explorar essa questão em mais detalhes. O que especificamente você gostaria de saber?",
147
+ "Ótima pergunta! Para te dar a melhor resposta possível, preciso entender melhor o contexto. Você pode me fornecer mais informações sobre o que está buscando?",
148
+ "Estou analisando sua solicitação. Baseado nos dados do sistema Xertica, posso te ajudar com isso. Você gostaria de uma análise rápida ou um relatório completo?"
149
+ ];
150
+ return respostasGenericas[Math.floor(Math.random() * respostasGenericas.length)];
151
+ };
152
+
153
+ function useAssistant({
154
+ mode = "expanded",
155
+ isExpanded: controlledIsExpanded,
156
+ onToggle,
157
+ defaultTab = "chat",
158
+ demoMode = true,
159
+ customResponses = [],
160
+ initialMessages = [],
161
+ savedConversations = [],
162
+ suggestions: propSuggestions,
163
+ onSendMessage,
164
+ isProcessing = false,
165
+ responseGenerator,
166
+ richSuggestions = [],
167
+ onRichAction,
168
+ onEvaluation
169
+ } = {}) {
170
+ const { t } = reactI18next.useTranslation();
171
+ const isFullPage = mode === "fullPage";
172
+ const [internalIsExpanded, setInternalIsExpanded] = React.useState(controlledIsExpanded ?? true);
173
+ const isExpanded = controlledIsExpanded ?? internalIsExpanded;
174
+ const isMobile = useMobile.useIsMobile();
175
+ const [abaSelecionada, setAbaSelecionada] = React.useState(defaultTab);
176
+ const [mensagens, setMensagens] = React.useState(initialMessages);
177
+ const [mensagem, setMensagem] = React.useState("");
178
+ const [conversas, setConversas] = React.useState(savedConversations);
179
+ const [conversaAtual, setConversaAtual] = React.useState(null);
180
+ const [copiedId, setCopiedId] = React.useState(null);
181
+ const [generatingPodcastId, setGeneratingPodcastId] = React.useState(null);
182
+ const [executingCommand, setExecutingCommand] = React.useState(null);
183
+ const [savedSearches, setSavedSearches] = React.useState([]);
184
+ const [editingDocument, setEditingDocument] = React.useState(
185
+ null
186
+ );
187
+ const [showMoreSuggestions, setShowMoreSuggestions] = React.useState(false);
188
+ const [evaluationState, setEvaluationState] = React.useState({
189
+ isOpen: false,
190
+ messageId: null,
191
+ type: null,
192
+ category: null,
193
+ reason: ""
194
+ });
195
+ const messagesEndRef = React.useRef(null);
196
+ const fileInputRef = React.useRef(null);
197
+ const audioInputRef = React.useRef(null);
198
+ const responseTimerRef = React.useRef(null);
199
+ const commandTimerRef = React.useRef(null);
200
+ const hydratedRef = React.useRef(false);
201
+ const defaultSuggestions = React.useMemo(
202
+ () => [
203
+ { id: "1", text: t("assistant.defaultSuggestions.createDocument") },
204
+ { id: "2", text: t("assistant.defaultSuggestions.searchFiles") },
205
+ { id: "3", text: t("assistant.defaultSuggestions.summarizeConversations") },
206
+ { id: "4", text: t("assistant.defaultSuggestions.createPodcast") }
207
+ ],
208
+ [t]
209
+ );
210
+ const sugestoes = propSuggestions ?? defaultSuggestions;
211
+ React.useEffect(() => {
212
+ return () => {
213
+ if (responseTimerRef.current) clearTimeout(responseTimerRef.current);
214
+ if (commandTimerRef.current) clearTimeout(commandTimerRef.current);
215
+ };
216
+ }, []);
217
+ React.useEffect(() => {
218
+ if (messagesEndRef.current && abaSelecionada === "chat") {
219
+ const container = messagesEndRef.current.parentElement;
220
+ if (!container) {
221
+ messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
222
+ return;
223
+ }
224
+ const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
225
+ if (distanceFromBottom < 120) {
226
+ messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
227
+ }
228
+ }
229
+ }, [mensagens, abaSelecionada]);
230
+ React.useEffect(() => {
231
+ if (!hydratedRef.current && initialMessages && initialMessages.length > 0) {
232
+ setMensagens(initialMessages);
233
+ hydratedRef.current = true;
234
+ }
235
+ }, [initialMessages]);
236
+ const conversasFiltradas = React.useMemo(
237
+ () => conversas.filter((c) => abaSelecionada === "favoritos" ? c.isFavorite : true),
238
+ [conversas, abaSelecionada]
239
+ );
240
+ const handleToggle = React.useCallback(() => {
241
+ if (onToggle) {
242
+ onToggle();
243
+ } else {
244
+ setInternalIsExpanded((prev) => !prev);
245
+ }
246
+ }, [onToggle]);
247
+ const handleExpandWithTab = React.useCallback(
248
+ (tab) => {
249
+ setAbaSelecionada(tab);
250
+ if (onToggle) {
251
+ onToggle();
252
+ } else {
253
+ setInternalIsExpanded(true);
254
+ }
255
+ },
256
+ [onToggle]
257
+ );
258
+ const handleEnviarMensagem = React.useCallback(
259
+ async (arg) => {
260
+ let msgToSend = mensagem;
261
+ if (typeof arg === "string" && !["document", "podcast", "search"].includes(arg)) {
262
+ msgToSend = arg;
263
+ }
264
+ if (!msgToSend.trim() || isProcessing) return;
265
+ const novaMensagem = {
266
+ id: `msg-${Date.now()}`,
267
+ type: "user",
268
+ content: msgToSend,
269
+ timestamp: /* @__PURE__ */ new Date(),
270
+ isFavorite: false
271
+ };
272
+ setMensagens((prev) => [...prev, novaMensagem]);
273
+ if (onSendMessage) {
274
+ onSendMessage(msgToSend);
275
+ }
276
+ if (demoMode || responseGenerator) {
277
+ const mensagemAtual = msgToSend;
278
+ responseTimerRef.current = setTimeout(
279
+ async () => {
280
+ let resposta;
281
+ if (responseGenerator) {
282
+ resposta = await responseGenerator(mensagemAtual);
283
+ } else {
284
+ resposta = gerarResposta(mensagemAtual, customResponses);
285
+ }
286
+ let novaMensagemIA = {
287
+ id: `msg-${Date.now()}-ia`,
288
+ type: "assistant",
289
+ content: "",
290
+ timestamp: /* @__PURE__ */ new Date(),
291
+ isFavorite: false
292
+ };
293
+ if (typeof resposta === "string") {
294
+ novaMensagemIA.content = resposta;
295
+ } else {
296
+ novaMensagemIA = { ...novaMensagemIA, ...resposta };
297
+ }
298
+ setMensagens((prev) => [...prev, novaMensagemIA]);
299
+ },
300
+ 1e3 + Math.random() * 1e3
301
+ );
302
+ }
303
+ setMensagem("");
304
+ },
305
+ [mensagem, isProcessing, onSendMessage, demoMode, responseGenerator, customResponses]
306
+ );
307
+ const handleToggleFavorite = React.useCallback((messageId) => {
308
+ setMensagens(
309
+ (prev) => prev.map((msg) => msg.id === messageId ? { ...msg, isFavorite: !msg.isFavorite } : msg)
310
+ );
311
+ }, []);
312
+ const handleCopyMessage = React.useCallback(async (content, messageId) => {
313
+ try {
314
+ if (navigator.clipboard && navigator.clipboard.writeText) {
315
+ try {
316
+ await navigator.clipboard.writeText(content);
317
+ setCopiedId(messageId);
318
+ setTimeout(() => setCopiedId(null), 2e3);
319
+ } catch (clipboardError) {
320
+ if (clipboardError.name === "NotAllowedError" || clipboardError.message.includes("permissions policy")) {
321
+ throw new Error("Clipboard permission denied, falling back");
322
+ }
323
+ throw clipboardError;
324
+ }
325
+ } else {
326
+ throw new Error("Clipboard API not available");
327
+ }
328
+ } catch {
329
+ try {
330
+ const textArea = document.createElement("textarea");
331
+ textArea.value = content;
332
+ textArea.style.position = "fixed";
333
+ textArea.style.left = "-999999px";
334
+ textArea.style.top = "-999999px";
335
+ document.body.appendChild(textArea);
336
+ textArea.focus();
337
+ textArea.select();
338
+ const successful = document.execCommand("copy");
339
+ document.body.removeChild(textArea);
340
+ if (successful) {
341
+ setCopiedId(messageId);
342
+ setTimeout(() => setCopiedId(null), 2e3);
343
+ }
344
+ } catch (fallbackErr) {
345
+ console.error("Falha ao copiar:", fallbackErr);
346
+ }
347
+ }
348
+ }, []);
349
+ const handleGeneratePodcast = React.useCallback(async (messageId, content) => {
350
+ setGeneratingPodcastId(messageId);
351
+ setTimeout(() => {
352
+ setMensagens(
353
+ (prev) => prev.map(
354
+ (msg) => msg.id === messageId ? {
355
+ ...msg,
356
+ attachmentType: "podcast",
357
+ attachmentName: `${t("assistant.podcastName")} - ${content.substring(0, 30)}...`,
358
+ audioUrl: "data:audio/mpeg;base64,//uQx..."
359
+ } : msg
360
+ )
361
+ );
362
+ setGeneratingPodcastId(null);
363
+ }, 2e3);
364
+ }, []);
365
+ const handleDownloadDocument = React.useCallback((content, fileName) => {
366
+ const blob = new Blob([content], { type: "text/markdown" });
367
+ const url = URL.createObjectURL(blob);
368
+ const a = document.createElement("a");
369
+ a.href = url;
370
+ a.download = fileName.endsWith(".md") ? fileName : fileName + ".md";
371
+ document.body.appendChild(a);
372
+ a.click();
373
+ document.body.removeChild(a);
374
+ URL.revokeObjectURL(url);
375
+ }, []);
376
+ const handleDownloadPodcast = React.useCallback((audioUrl, fileName) => {
377
+ const a = document.createElement("a");
378
+ a.href = audioUrl;
379
+ a.download = fileName.endsWith(".mp3") ? fileName : fileName + ".mp3";
380
+ document.body.appendChild(a);
381
+ a.click();
382
+ document.body.removeChild(a);
383
+ }, []);
384
+ const handleEditDocument = React.useCallback((content, title) => {
385
+ setEditingDocument({ content, title });
386
+ }, []);
387
+ const handleNovaConversa = React.useCallback(() => {
388
+ setMensagens([]);
389
+ setConversaAtual(null);
390
+ setAbaSelecionada("chat");
391
+ }, []);
392
+ const handleSelecionarConversa = React.useCallback(
393
+ (conversaId) => {
394
+ const conversa = conversas.find((c) => c.id === conversaId);
395
+ if (conversa) {
396
+ setMensagens(conversa.messages);
397
+ setConversaAtual(conversaId);
398
+ setAbaSelecionada("chat");
399
+ }
400
+ },
401
+ [conversas]
402
+ );
403
+ const handleToggleFavoritaConversa = React.useCallback((conversaId) => {
404
+ setConversas(
405
+ (prev) => prev.map((conv) => conv.id === conversaId ? { ...conv, isFavorite: !conv.isFavorite } : conv)
406
+ );
407
+ }, []);
408
+ const handleOpenSearchResult = React.useCallback((result) => {
409
+ console.log("Abrir resultado:", result);
410
+ }, []);
411
+ const handleExecuteSearchCommand = React.useCallback(
412
+ async (commandId, searchTerm, results, messageId) => {
413
+ setExecutingCommand(commandId);
414
+ commandTimerRef.current = setTimeout(() => {
415
+ if (commandId === "5") {
416
+ setSavedSearches((prev) => [...prev, messageId]);
417
+ }
418
+ setExecutingCommand(null);
419
+ }, 1500);
420
+ },
421
+ []
422
+ );
423
+ const handleRichSuggestionClick = React.useCallback(
424
+ (suggestion) => {
425
+ if (onRichAction) {
426
+ onRichAction(suggestion.id, suggestion.text);
427
+ } else {
428
+ handleEnviarMensagem(suggestion.text);
429
+ }
430
+ setShowMoreSuggestions(false);
431
+ },
432
+ [onRichAction, handleEnviarMensagem]
433
+ );
434
+ const handleEvaluationClick = React.useCallback(
435
+ (messageId, type) => {
436
+ if (type === "like") {
437
+ if (onEvaluation) onEvaluation(messageId, "like");
438
+ setMensagens(
439
+ (prev) => prev.map((m) => m.id === messageId ? { ...m, evaluation: "like" } : m)
440
+ );
441
+ sonner.toast.success(t("assistant.likeToast"));
442
+ }
443
+ },
444
+ [onEvaluation]
445
+ );
446
+ const openFeedbackDialog = React.useCallback((messageId, category) => {
447
+ setEvaluationState({
448
+ isOpen: true,
449
+ messageId,
450
+ type: "dislike",
451
+ category,
452
+ reason: ""
453
+ });
454
+ }, []);
455
+ const handleSubmitDislike = React.useCallback(() => {
456
+ if (evaluationState.messageId) {
457
+ const finalReason = evaluationState.category ? evaluationState.reason ? `${evaluationState.category}: ${evaluationState.reason}` : evaluationState.category : evaluationState.reason;
458
+ if (onEvaluation) {
459
+ onEvaluation(evaluationState.messageId, "dislike", finalReason);
460
+ }
461
+ setMensagens(
462
+ (prev) => prev.map(
463
+ (m) => m.id === evaluationState.messageId ? { ...m, evaluation: "dislike", evaluationReason: finalReason } : m
464
+ )
465
+ );
466
+ sonner.toast.success(t("assistant.feedbackToast"));
467
+ }
468
+ setEvaluationState({ isOpen: false, messageId: null, type: null, category: null, reason: "" });
469
+ }, [evaluationState, onEvaluation]);
470
+ return {
471
+ // Layout
472
+ isFullPage,
473
+ isExpanded,
474
+ isMobile,
475
+ abaSelecionada,
476
+ setAbaSelecionada,
477
+ // Messages
478
+ mensagens,
479
+ setMensagens,
480
+ mensagem,
481
+ setMensagem,
482
+ // Conversations
483
+ conversas,
484
+ conversaAtual,
485
+ conversasFiltradas,
486
+ // UI
487
+ copiedId,
488
+ generatingPodcastId,
489
+ executingCommand,
490
+ savedSearches,
491
+ editingDocument,
492
+ setEditingDocument,
493
+ showMoreSuggestions,
494
+ setShowMoreSuggestions,
495
+ evaluationState,
496
+ setEvaluationState,
497
+ // Suggestions
498
+ sugestoes,
499
+ // Refs
500
+ messagesEndRef,
501
+ fileInputRef,
502
+ audioInputRef,
503
+ // Handlers
504
+ handleToggle,
505
+ handleExpandWithTab,
506
+ handleEnviarMensagem,
507
+ handleToggleFavorite,
508
+ handleCopyMessage,
509
+ handleGeneratePodcast,
510
+ handleDownloadDocument,
511
+ handleDownloadPodcast,
512
+ handleEditDocument,
513
+ handleNovaConversa,
514
+ handleSelecionarConversa,
515
+ handleToggleFavoritaConversa,
516
+ handleOpenSearchResult,
517
+ handleExecuteSearchCommand,
518
+ handleRichSuggestionClick,
519
+ handleEvaluationClick,
520
+ openFeedbackDialog,
521
+ handleSubmitDislike
522
+ };
523
+ }
524
+
525
+ function ModernChatInput({
526
+ value,
527
+ onChange,
528
+ onSubmit,
529
+ placeholder,
530
+ disabled = false,
531
+ onFileUpload,
532
+ onAudioUpload,
533
+ onVoiceRecording,
534
+ isFullPage = false,
535
+ enableAudioInput = true,
536
+ enableFileAttachment = true,
537
+ enableDocumentCreation = true,
538
+ enablePodcastGeneration = true,
539
+ enableSearch = true
540
+ }) {
541
+ const { t } = reactI18next.useTranslation();
542
+ const textareaRef = React.useRef(null);
543
+ const [isFocused, setIsFocused] = React.useState(false);
544
+ const [textareaHeight, setTextareaHeight] = React.useState(20);
545
+ const [selectedAction, setSelectedAction] = React.useState(null);
546
+ const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
547
+ const [isRecording, setIsRecording] = React.useState(false);
548
+ const [recordingTime, setRecordingTime] = React.useState(0);
549
+ const recordingIntervalRef = React.useRef(null);
550
+ const resolvedPlaceholder = placeholder ?? t("assistant.inputPlaceholder");
551
+ const adjustHeight = () => {
552
+ const textarea = textareaRef.current;
553
+ if (textarea) {
554
+ textarea.style.height = "20px";
555
+ const scrollHeight = textarea.scrollHeight;
556
+ const newHeight = Math.min(Math.max(scrollHeight, 20), 100);
557
+ setTextareaHeight(newHeight);
558
+ textarea.style.height = newHeight + "px";
559
+ }
560
+ };
561
+ React.useEffect(() => {
562
+ const textarea = textareaRef.current;
563
+ if (textarea) {
564
+ textarea.style.height = "20px";
565
+ setTextareaHeight(20);
566
+ if (value) {
567
+ setTimeout(adjustHeight, 0);
568
+ }
569
+ }
570
+ }, []);
571
+ React.useEffect(() => {
572
+ if (value === "") {
573
+ const textarea = textareaRef.current;
574
+ if (textarea) {
575
+ textarea.style.height = "20px";
576
+ setTextareaHeight(20);
577
+ }
578
+ } else {
579
+ const timeoutId = setTimeout(adjustHeight, 0);
580
+ return () => clearTimeout(timeoutId);
581
+ }
582
+ }, [value]);
583
+ const handleKeyDown = (e) => {
584
+ if (e.key === "Enter" && !e.shiftKey) {
585
+ e.preventDefault();
586
+ if (value.trim() && !disabled) {
587
+ onSubmit(selectedAction);
588
+ setSelectedAction(null);
589
+ }
590
+ }
591
+ };
592
+ const handleActionSelect = (action) => {
593
+ setSelectedAction(action);
594
+ setIsPopoverOpen(false);
595
+ };
596
+ const handleRemoveAction = () => {
597
+ setSelectedAction(null);
598
+ };
599
+ const handleVoiceRecording = () => {
600
+ if (isRecording) {
601
+ if (recordingIntervalRef.current) {
602
+ clearInterval(recordingIntervalRef.current);
603
+ recordingIntervalRef.current = null;
604
+ }
605
+ const transcricoes = [
606
+ t("assistant.voiceTranscriptions.salesData"),
607
+ t("assistant.voiceTranscriptions.performanceReport"),
608
+ t("assistant.voiceTranscriptions.marketTrends"),
609
+ t("assistant.voiceTranscriptions.customerSatisfaction"),
610
+ t("assistant.voiceTranscriptions.teamProductivity"),
611
+ t("assistant.voiceTranscriptions.keyMetrics"),
612
+ t("assistant.voiceTranscriptions.digitalMarketing"),
613
+ t("assistant.voiceTranscriptions.socialEngagement")
614
+ ];
615
+ const transcricaoAleatoria = transcricoes[Math.floor(Math.random() * transcricoes.length)];
616
+ if (onVoiceRecording) {
617
+ onVoiceRecording(transcricaoAleatoria);
618
+ }
619
+ setIsRecording(false);
620
+ setRecordingTime(0);
621
+ } else {
622
+ setIsRecording(true);
623
+ setRecordingTime(0);
624
+ sonner.toast.info(t("assistant.recordingStarted"), {
625
+ description: t("assistant.recordingDescriptionFull"),
626
+ duration: 3e3
627
+ });
628
+ recordingIntervalRef.current = setInterval(() => {
629
+ setRecordingTime((prev) => prev + 1);
630
+ }, 1e3);
631
+ }
632
+ };
633
+ React.useEffect(() => {
634
+ if (recordingTime >= 60 && isRecording) {
635
+ handleVoiceRecording();
636
+ }
637
+ }, [recordingTime, isRecording]);
638
+ React.useEffect(() => {
639
+ return () => {
640
+ if (recordingIntervalRef.current) {
641
+ clearInterval(recordingIntervalRef.current);
642
+ }
643
+ };
644
+ }, []);
645
+ const getActionInfo = (action) => {
646
+ switch (action) {
647
+ case "document":
648
+ return {
649
+ label: t("assistant.actions.createDocument"),
650
+ icon: lucideReact.FileText,
651
+ color: "bg-[var(--chart-4)]"
652
+ };
653
+ case "podcast":
654
+ return {
655
+ label: t("assistant.actions.generatePodcast"),
656
+ icon: lucideReact.Radio,
657
+ color: "bg-[var(--chart-1)]"
658
+ };
659
+ case "search":
660
+ return { label: t("assistant.actions.search"), icon: lucideReact.Search, color: "bg-[var(--chart-2)]" };
661
+ default:
662
+ return null;
663
+ }
664
+ };
665
+ const handleFocus = () => setIsFocused(true);
666
+ const handleBlur = () => setIsFocused(false);
667
+ const hasContent = value.trim().length > 0;
668
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `p-4 ${isFullPage ? "mx-auto w-full max-w-6xl" : ""}`, children: [
669
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isRecording && /* @__PURE__ */ jsxRuntime.jsx(
670
+ framerMotion.motion.div,
671
+ {
672
+ initial: { opacity: 0, y: 10 },
673
+ animate: { opacity: 1, y: 0 },
674
+ exit: { opacity: 0, y: 10 },
675
+ className: "mb-3 p-4 bg-destructive/10 border border-destructive/30 rounded-[var(--radius-card)]",
676
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
677
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
678
+ /* @__PURE__ */ jsxRuntime.jsx(
679
+ framerMotion.motion.div,
680
+ {
681
+ animate: {
682
+ scale: [1, 1.2, 1],
683
+ opacity: [1, 0.7, 1]
684
+ },
685
+ transition: {
686
+ duration: 1.5,
687
+ repeat: Infinity,
688
+ ease: "easeInOut"
689
+ },
690
+ className: "w-3 h-3 bg-destructive rounded-full"
691
+ }
692
+ ),
693
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: [0, 1, 2, 3, 4].map((i) => /* @__PURE__ */ jsxRuntime.jsx(
694
+ framerMotion.motion.div,
695
+ {
696
+ animate: {
697
+ height: ["8px", "20px", "8px"]
698
+ },
699
+ transition: {
700
+ duration: 0.8,
701
+ repeat: Infinity,
702
+ ease: "easeInOut",
703
+ delay: i * 0.1
704
+ },
705
+ className: "w-1 bg-destructive rounded-full h-2"
706
+ },
707
+ i
708
+ )) }),
709
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-destructive", children: t("assistant.recordingAudio") })
710
+ ] }),
711
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
712
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-destructive font-mono tabular-nums", children: [
713
+ Math.floor(recordingTime / 60),
714
+ ":",
715
+ (recordingTime % 60).toString().padStart(2, "0")
716
+ ] }),
717
+ /* @__PURE__ */ jsxRuntime.jsx(
718
+ button.Button,
719
+ {
720
+ onClick: handleVoiceRecording,
721
+ size: "sm",
722
+ variant: "outline",
723
+ className: "h-7 px-3 text-xs border-destructive/30 text-destructive hover:bg-destructive/10 rounded-[var(--radius-button)]",
724
+ children: t("assistant.stopRecording")
725
+ }
726
+ )
727
+ ] })
728
+ ] })
729
+ }
730
+ ) }),
731
+ /* @__PURE__ */ jsxRuntime.jsxs(
732
+ framerMotion.motion.div,
733
+ {
734
+ className: `relative bg-card rounded-[var(--radius)] border shadow-sm transition-all duration-300 ${isFocused || hasContent ? "border-primary shadow-lg shadow-primary/10" : "border-border"}`,
735
+ initial: false,
736
+ animate: {
737
+ scale: isFocused ? 1.01 : 1
738
+ },
739
+ transition: { duration: 0.2, ease: "easeOut" },
740
+ children: [
741
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2 pt-[14px] pr-[10px] pb-[8px] pl-[10px] rounded-[var(--radius)]", children: [
742
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: selectedAction && /* @__PURE__ */ jsxRuntime.jsx(
743
+ framerMotion.motion.div,
744
+ {
745
+ initial: { opacity: 0, y: -10, height: 0 },
746
+ animate: { opacity: 1, y: 0, height: "auto" },
747
+ exit: { opacity: 0, y: -10, height: 0 },
748
+ transition: { duration: 0.2 },
749
+ className: "mb-2",
750
+ children: (() => {
751
+ const actionInfo = getActionInfo(selectedAction);
752
+ if (!actionInfo) return null;
753
+ const Icon = actionInfo.icon;
754
+ return /* @__PURE__ */ jsxRuntime.jsxs(
755
+ "div",
756
+ {
757
+ className: `inline-flex items-center gap-2 px-3 py-1.5 rounded-full ${actionInfo.color} text-white text-xs font-medium shadow-sm`,
758
+ children: [
759
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-3.5 h-3.5" }),
760
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: actionInfo.label }),
761
+ /* @__PURE__ */ jsxRuntime.jsx(
762
+ "button",
763
+ {
764
+ onClick: handleRemoveAction,
765
+ className: "ml-1 hover:bg-white/20 rounded-full p-0.5 transition-colors",
766
+ "aria-label": t("assistant.removeAction"),
767
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
768
+ }
769
+ )
770
+ ]
771
+ }
772
+ );
773
+ })()
774
+ }
775
+ ) }),
776
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsx(
777
+ "textarea",
778
+ {
779
+ ref: textareaRef,
780
+ value,
781
+ onChange: (e) => onChange(e.target.value),
782
+ onKeyDown: handleKeyDown,
783
+ onFocus: handleFocus,
784
+ onBlur: handleBlur,
785
+ placeholder: resolvedPlaceholder,
786
+ "aria-label": resolvedPlaceholder,
787
+ disabled,
788
+ className: "w-full bg-transparent border-0 outline-none resize-none text-foreground placeholder-muted-foreground text-sm leading-5 min-h-[20px] max-h-[100px] overflow-y-auto scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent",
789
+ style: {
790
+ height: `${textareaHeight}px`,
791
+ minHeight: "20px",
792
+ maxHeight: "100px"
793
+ },
794
+ rows: 1
795
+ }
796
+ ) }),
797
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
798
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
799
+ (enableDocumentCreation || enablePodcastGeneration || enableSearch) && /* @__PURE__ */ jsxRuntime.jsxs(input.Popover, { open: isPopoverOpen, onOpenChange: setIsPopoverOpen, children: [
800
+ /* @__PURE__ */ jsxRuntime.jsx(input.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
801
+ button.Button,
802
+ {
803
+ variant: "ghost",
804
+ size: "sm",
805
+ className: "h-8 w-8 p-0 rounded-full text-muted-foreground hover:bg-accent hover:text-foreground transition-all duration-200",
806
+ "aria-label": t("assistant.viewActions"),
807
+ children: /* @__PURE__ */ jsxRuntime.jsx(
808
+ framerMotion.motion.div,
809
+ {
810
+ whileHover: { scale: 1.05 },
811
+ whileTap: { scale: 0.95 },
812
+ className: "flex items-center justify-center w-full h-full",
813
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "w-4 h-4" })
814
+ }
815
+ )
816
+ }
817
+ ) }),
818
+ /* @__PURE__ */ jsxRuntime.jsx(input.PopoverContent, { className: "w-56 p-2", align: "start", side: "top", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
819
+ enableDocumentCreation && /* @__PURE__ */ jsxRuntime.jsxs(
820
+ "button",
821
+ {
822
+ onClick: () => handleActionSelect("document"),
823
+ className: "w-full flex items-center gap-3 px-3 py-2.5 rounded-lg hover:bg-accent transition-colors text-left group",
824
+ children: [
825
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 rounded-full bg-[var(--chart-4)]/20 flex items-center justify-center group-hover:bg-[var(--chart-4)] transition-colors", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "w-4 h-4 text-[var(--chart-4)] group-hover:text-white" }) }),
826
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
827
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: t("assistant.actions.createDocument") }),
828
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: t("assistant.actions.createDocumentDesc") })
829
+ ] })
830
+ ]
831
+ }
832
+ ),
833
+ enablePodcastGeneration && /* @__PURE__ */ jsxRuntime.jsxs(
834
+ "button",
835
+ {
836
+ onClick: () => handleActionSelect("podcast"),
837
+ className: "w-full flex items-center gap-3 px-3 py-2.5 rounded-lg hover:bg-accent transition-colors text-left group",
838
+ children: [
839
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 rounded-full bg-[var(--chart-1)]/20 flex items-center justify-center group-hover:bg-[var(--chart-1)] transition-colors", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Radio, { className: "w-4 h-4 text-[var(--chart-1)] group-hover:text-white" }) }),
840
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
841
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: t("assistant.actions.generatePodcast") }),
842
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: t("assistant.actions.generatePodcastDesc") })
843
+ ] })
844
+ ]
845
+ }
846
+ ),
847
+ enableSearch && /* @__PURE__ */ jsxRuntime.jsxs(
848
+ "button",
849
+ {
850
+ onClick: () => handleActionSelect("search"),
851
+ className: "w-full flex items-center gap-3 px-3 py-2.5 rounded-lg hover:bg-accent transition-colors text-left group",
852
+ children: [
853
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 rounded-full bg-[var(--chart-2)]/20 flex items-center justify-center group-hover:bg-[var(--chart-2)] transition-colors", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "w-4 h-4 text-[var(--chart-2)] group-hover:text-white" }) }),
854
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
855
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: t("assistant.actions.search") }),
856
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: t("assistant.actions.searchDesc") })
857
+ ] })
858
+ ]
859
+ }
860
+ )
861
+ ] }) })
862
+ ] }),
863
+ enableFileAttachment && /* @__PURE__ */ jsxRuntime.jsx(framerMotion.motion.div, { whileHover: { scale: 1.05 }, whileTap: { scale: 0.95 }, children: /* @__PURE__ */ jsxRuntime.jsx(
864
+ button.Button,
865
+ {
866
+ variant: "ghost",
867
+ size: "sm",
868
+ onClick: onFileUpload,
869
+ className: "h-8 w-8 p-0 rounded-full text-muted-foreground hover:bg-accent hover:text-foreground transition-all duration-200",
870
+ "aria-label": t("assistant.attachFile"),
871
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Paperclip, { className: "w-4 h-4" })
872
+ }
873
+ ) })
874
+ ] }),
875
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
876
+ enableAudioInput && /* @__PURE__ */ jsxRuntime.jsx(framerMotion.motion.div, { whileHover: { scale: 1.05 }, whileTap: { scale: 0.95 }, children: /* @__PURE__ */ jsxRuntime.jsx(
877
+ button.Button,
878
+ {
879
+ variant: "ghost",
880
+ size: "sm",
881
+ onClick: handleVoiceRecording,
882
+ className: `h-8 w-8 p-0 rounded-full transition-all duration-200 ${isRecording ? "bg-destructive hover:bg-destructive/90 text-white animate-pulse" : "text-muted-foreground hover:bg-accent hover:text-foreground"}`,
883
+ "aria-label": isRecording ? t("assistant.stopRecording") : t("assistant.suggestWithVoice"),
884
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mic, { className: "w-4 h-4" })
885
+ }
886
+ ) }),
887
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsx(
888
+ framerMotion.motion.div,
889
+ {
890
+ initial: { scale: 0.8, opacity: 0 },
891
+ animate: { scale: 1, opacity: 1 },
892
+ exit: { scale: 0.8, opacity: 0 },
893
+ transition: { duration: 0.2, ease: "easeInOut" },
894
+ whileHover: hasContent ? { scale: 1.05 } : {},
895
+ whileTap: hasContent ? { scale: 0.95 } : {},
896
+ children: /* @__PURE__ */ jsxRuntime.jsx(
897
+ button.Button,
898
+ {
899
+ onClick: () => {
900
+ onSubmit(selectedAction);
901
+ setSelectedAction(null);
902
+ },
903
+ size: "sm",
904
+ disabled: !hasContent || disabled,
905
+ className: `h-8 w-8 p-0 rounded-full transition-all duration-300 ${hasContent && !disabled ? "bg-primary hover:bg-primary/90 text-primary-foreground shadow-lg shadow-primary/30 hover:shadow-primary/40" : "bg-muted text-muted-foreground cursor-not-allowed"}`,
906
+ "aria-label": t("assistant.sendMessage"),
907
+ children: /* @__PURE__ */ jsxRuntime.jsx(
908
+ framerMotion.motion.div,
909
+ {
910
+ animate: {
911
+ rotate: hasContent ? 0 : -45
912
+ },
913
+ transition: { duration: 0.2 },
914
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "w-4 h-4" })
915
+ }
916
+ )
917
+ }
918
+ )
919
+ },
920
+ hasContent ? "active" : "inactive"
921
+ ) })
922
+ ] })
923
+ ] })
924
+ ] }),
925
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isFocused && /* @__PURE__ */ jsxRuntime.jsx(
926
+ framerMotion.motion.div,
927
+ {
928
+ className: "absolute inset-0 rounded-[var(--radius)] bg-gradient-to-r from-primary/5 via-transparent to-primary/5 pointer-events-none",
929
+ initial: { opacity: 0 },
930
+ animate: { opacity: 1 },
931
+ exit: { opacity: 0 },
932
+ transition: { duration: 0.3 }
933
+ }
934
+ ) })
935
+ ]
936
+ }
937
+ ),
938
+ /* @__PURE__ */ jsxRuntime.jsx(
939
+ framerMotion.motion.div,
940
+ {
941
+ className: "mt-2 text-center",
942
+ initial: { opacity: 0, y: 5 },
943
+ animate: { opacity: 1, y: 0 },
944
+ transition: { delay: 0.1 },
945
+ children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: t("assistant.disclaimer") })
946
+ }
947
+ )
948
+ ] });
949
+ }
950
+
951
+ function AssistantCollapsedView({
952
+ showHistory,
953
+ showFavorites,
954
+ onToggle,
955
+ onExpandWithTab
956
+ }) {
957
+ const { t } = reactI18next.useTranslation();
958
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center p-4 space-y-4", children: [
959
+ /* @__PURE__ */ jsxRuntime.jsxs(tooltip.Tooltip, { children: [
960
+ /* @__PURE__ */ jsxRuntime.jsx(tooltip.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
961
+ "button",
962
+ {
963
+ onClick: onToggle,
964
+ className: "w-10 h-10 rounded-full flex items-center justify-center hover:bg-accent/50 transition-colors duration-200 cursor-pointer mx-auto",
965
+ "aria-label": t("assistant.open"),
966
+ children: /* @__PURE__ */ jsxRuntime.jsx(XerticaOrbe.XerticaOrbe, { size: 32 })
967
+ }
968
+ ) }),
969
+ /* @__PURE__ */ jsxRuntime.jsx(CustomTooltipContent.CustomTooltipContent, { side: "left", sideOffset: 8, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: t("assistant.title") }) })
970
+ ] }),
971
+ /* @__PURE__ */ jsxRuntime.jsxs(tooltip.Tooltip, { children: [
972
+ /* @__PURE__ */ jsxRuntime.jsx(tooltip.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
973
+ button.Button,
974
+ {
975
+ variant: "ghost",
976
+ size: "sm",
977
+ onClick: () => onExpandWithTab("chat"),
978
+ className: "w-8 h-8 p-0 text-muted-foreground",
979
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "w-4 h-4" })
980
+ }
981
+ ) }),
982
+ /* @__PURE__ */ jsxRuntime.jsx(CustomTooltipContent.CustomTooltipContent, { side: "left", sideOffset: 8, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: t("assistant.tabs.chat") }) })
983
+ ] }),
984
+ showFavorites && /* @__PURE__ */ jsxRuntime.jsxs(tooltip.Tooltip, { children: [
985
+ /* @__PURE__ */ jsxRuntime.jsx(tooltip.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
986
+ button.Button,
987
+ {
988
+ variant: "ghost",
989
+ size: "sm",
990
+ onClick: () => onExpandWithTab("favoritos"),
991
+ className: "w-8 h-8 p-0 text-muted-foreground",
992
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heart, { className: "w-4 h-4" })
993
+ }
994
+ ) }),
995
+ /* @__PURE__ */ jsxRuntime.jsx(CustomTooltipContent.CustomTooltipContent, { side: "left", sideOffset: 8, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: t("assistant.tabs.favorites") }) })
996
+ ] }),
997
+ showHistory && /* @__PURE__ */ jsxRuntime.jsxs(tooltip.Tooltip, { children: [
998
+ /* @__PURE__ */ jsxRuntime.jsx(tooltip.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
999
+ button.Button,
1000
+ {
1001
+ variant: "ghost",
1002
+ size: "sm",
1003
+ onClick: () => onExpandWithTab("historico"),
1004
+ className: "w-8 h-8 p-0 text-muted-foreground",
1005
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "w-4 h-4" })
1006
+ }
1007
+ ) }),
1008
+ /* @__PURE__ */ jsxRuntime.jsx(CustomTooltipContent.CustomTooltipContent, { side: "left", sideOffset: 8, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: t("assistant.tabs.history") }) })
1009
+ ] })
1010
+ ] });
1011
+ }
1012
+
1013
+ function AssistantHeader({
1014
+ isExpanded,
1015
+ onToggle,
1016
+ onNavigateFullPage
1017
+ }) {
1018
+ const { t } = reactI18next.useTranslation();
1019
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1020
+ "div",
1021
+ {
1022
+ className: button.cn(
1023
+ "border-b border-border flex items-center h-[64px]",
1024
+ isExpanded ? "justify-between px-4" : "justify-center px-0"
1025
+ ),
1026
+ children: [
1027
+ isExpanded && /* @__PURE__ */ jsxRuntime.jsxs(
1028
+ framerMotion.motion.div,
1029
+ {
1030
+ initial: { opacity: 0, x: -10 },
1031
+ animate: { opacity: 1, x: 0 },
1032
+ exit: { opacity: 0, x: -10 },
1033
+ className: "flex items-center gap-2 overflow-hidden",
1034
+ children: [
1035
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(XerticaOrbe.XerticaOrbe, { size: 32 }) }),
1036
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-medium truncate", children: t("assistant.title") })
1037
+ ]
1038
+ }
1039
+ ),
1040
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
1041
+ isExpanded && onNavigateFullPage && /* @__PURE__ */ jsxRuntime.jsx(
1042
+ button.Button,
1043
+ {
1044
+ variant: "ghost",
1045
+ size: "sm",
1046
+ onClick: onNavigateFullPage,
1047
+ className: "h-8 w-8 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-full",
1048
+ title: t("assistant.expand"),
1049
+ "aria-label": t("assistant.expand"),
1050
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize2, { className: "w-4 h-4" })
1051
+ }
1052
+ ),
1053
+ /* @__PURE__ */ jsxRuntime.jsx(
1054
+ button.Button,
1055
+ {
1056
+ variant: "ghost",
1057
+ size: "sm",
1058
+ onClick: onToggle,
1059
+ className: button.cn(
1060
+ "h-8 w-8 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-full",
1061
+ !isExpanded && "w-10 h-10"
1062
+ ),
1063
+ "aria-label": isExpanded ? t("assistant.collapse") : t("assistant.expand"),
1064
+ children: isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelRight, { className: "w-4 h-4" })
1065
+ }
1066
+ )
1067
+ ] })
1068
+ ]
1069
+ }
1070
+ );
1071
+ }
1072
+
1073
+ function AssistantTabBar({
1074
+ activeTab,
1075
+ showHistory,
1076
+ showFavorites,
1077
+ onTabChange
1078
+ }) {
1079
+ const { t } = reactI18next.useTranslation();
1080
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1", children: [
1081
+ /* @__PURE__ */ jsxRuntime.jsxs(
1082
+ button.Button,
1083
+ {
1084
+ variant: activeTab === "chat" ? "default" : "ghost",
1085
+ size: "sm",
1086
+ onClick: () => onTabChange("chat"),
1087
+ className: "flex-1 h-8",
1088
+ "aria-label": t("assistant.tabs.chatLabel"),
1089
+ children: [
1090
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "w-3 h-3 mr-1" }),
1091
+ t("assistant.tabs.chat")
1092
+ ]
1093
+ }
1094
+ ),
1095
+ showHistory && /* @__PURE__ */ jsxRuntime.jsxs(
1096
+ button.Button,
1097
+ {
1098
+ variant: activeTab === "historico" ? "default" : "ghost",
1099
+ size: "sm",
1100
+ onClick: () => onTabChange("historico"),
1101
+ className: "flex-1 h-8",
1102
+ "aria-label": t("assistant.tabs.historyLabel"),
1103
+ children: [
1104
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "w-3 h-3 mr-1" }),
1105
+ t("assistant.tabs.history")
1106
+ ]
1107
+ }
1108
+ ),
1109
+ showFavorites && /* @__PURE__ */ jsxRuntime.jsxs(
1110
+ button.Button,
1111
+ {
1112
+ variant: activeTab === "favoritos" ? "default" : "ghost",
1113
+ size: "sm",
1114
+ onClick: () => onTabChange("favoritos"),
1115
+ className: "flex-1 h-8",
1116
+ "aria-label": t("assistant.tabs.favoritesLabel"),
1117
+ children: [
1118
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heart, { className: "w-3 h-3 mr-1" }),
1119
+ t("assistant.tabs.favorites")
1120
+ ]
1121
+ }
1122
+ )
1123
+ ] }) });
1124
+ }
1125
+
1126
+ function AssistantWelcomeScreen({
1127
+ userName,
1128
+ welcomeMessage,
1129
+ suggestions,
1130
+ richSuggestions,
1131
+ showMoreSuggestions,
1132
+ onSetShowMoreSuggestions,
1133
+ onSendSuggestion,
1134
+ onRichSuggestionClick
1135
+ }) {
1136
+ const { t } = reactI18next.useTranslation();
1137
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto min-h-0", children: [
1138
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 text-center", children: [
1139
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto mb-4 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(XerticaOrbe.XerticaOrbe, { size: 64 }) }),
1140
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-2 text-foreground", children: t("assistant.greeting", { name: userName }) }),
1141
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: welcomeMessage })
1142
+ ] }),
1143
+ (suggestions.length > 0 || richSuggestions.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 pb-4 space-y-2", children: [
1144
+ suggestions.map((sugestao) => /* @__PURE__ */ jsxRuntime.jsx(
1145
+ "button",
1146
+ {
1147
+ onClick: () => onSendSuggestion(sugestao.text),
1148
+ className: "w-full p-3 text-left rounded-[var(--radius-card)] bg-muted text-foreground transition-colors duration-200 hover:bg-muted/80",
1149
+ children: sugestao.text
1150
+ },
1151
+ sugestao.id
1152
+ )),
1153
+ richSuggestions.length > 0 && (!showMoreSuggestions ? /* @__PURE__ */ jsxRuntime.jsxs(
1154
+ button.Button,
1155
+ {
1156
+ variant: "ghost",
1157
+ size: "sm",
1158
+ onClick: () => onSetShowMoreSuggestions(true),
1159
+ className: "w-full justify-start text-muted-foreground",
1160
+ children: [
1161
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontal, { className: "w-4 h-4 mr-2" }),
1162
+ t("assistant.moreSuggestions")
1163
+ ]
1164
+ }
1165
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 pt-2 border-t border-border mt-2 animate-in slide-in-from-top-2", children: [
1166
+ richSuggestions.map((sugestao) => /* @__PURE__ */ jsxRuntime.jsx(
1167
+ "button",
1168
+ {
1169
+ onClick: () => onRichSuggestionClick(sugestao),
1170
+ className: "w-full p-3 text-left rounded-[var(--radius-card)] bg-muted/50 border border-border text-foreground transition-all duration-200 hover:bg-primary/5 hover:border-primary/50 group",
1171
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1172
+ sugestao.id.includes("chart") && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BarChart3, { className: "w-4 h-4 text-primary" }),
1173
+ sugestao.id.includes("table") && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Table, { className: "w-4 h-4 text-primary" }),
1174
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: sugestao.text })
1175
+ ] })
1176
+ },
1177
+ sugestao.id
1178
+ )),
1179
+ /* @__PURE__ */ jsxRuntime.jsxs(
1180
+ button.Button,
1181
+ {
1182
+ variant: "ghost",
1183
+ size: "sm",
1184
+ onClick: () => onSetShowMoreSuggestions(false),
1185
+ className: "w-full justify-center text-muted-foreground mt-2",
1186
+ children: [
1187
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "w-4 h-4 mr-2" }),
1188
+ t("assistant.back")
1189
+ ]
1190
+ }
1191
+ )
1192
+ ] }))
1193
+ ] })
1194
+ ] });
1195
+ }
1196
+
1197
+ function MarkdownMessage({ content, className = "" }) {
1198
+ const convertMarkdownToHtml = (markdown) => {
1199
+ let html = markdown;
1200
+ html = html.replace(/</g, "<").replace(/>/g, ">");
1201
+ html = html.replace(
1202
+ /^### (.*$)/gim,
1203
+ '<h3 class="font-medium text-sm mt-2 mb-1 break-words">$1</h3>'
1204
+ );
1205
+ html = html.replace(
1206
+ /^## (.*$)/gim,
1207
+ '<h2 class="font-medium text-base mt-3 mb-1.5 break-words">$1</h2>'
1208
+ );
1209
+ html = html.replace(
1210
+ /^# (.*$)/gim,
1211
+ '<h1 class="font-medium text-lg mt-3 mb-2 break-words">$1</h1>'
1212
+ );
1213
+ html = html.replace(/\*\*(.*?)\*\*/g, '<strong class="font-medium">$1</strong>');
1214
+ html = html.replace(/\*(.*?)\*/g, '<em class="italic">$1</em>');
1215
+ html = html.replace(
1216
+ /\[([^\]]+)\]\(([^)]+)\)/g,
1217
+ '<a href="$2" class="text-[var(--chart-4)] hover:underline break-all" target="_blank" rel="noopener noreferrer">$1</a>'
1218
+ );
1219
+ html = html.replace(
1220
+ /`([^`]+)`/g,
1221
+ '<code class="px-1.5 py-0.5 rounded bg-muted text-xs font-mono break-all inline-block max-w-full">$1</code>'
1222
+ );
1223
+ html = html.replace(/((?:^[•\-] .*$(?:\n|$))+)/gim, (match) => {
1224
+ const items = match.trim().split("\n").map(
1225
+ (item) => `<li class="ml-4 mb-1 list-disc break-words">${item.replace(/^[•\-]\s+/, "")}</li>`
1226
+ ).join("");
1227
+ return `<ul class="list-disc my-2">${items}</ul>`;
1228
+ });
1229
+ html = html.replace(/((?:^\d+\. .*$(?:\n|$))+)/gim, (match) => {
1230
+ const items = match.trim().split("\n").map(
1231
+ (item) => `<li class="ml-4 mb-1 list-decimal break-words">${item.replace(/^\d+\.\s+/, "")}</li>`
1232
+ ).join("");
1233
+ return `<ol class="list-decimal my-2">${items}</ol>`;
1234
+ });
1235
+ html = html.replace(/((?:^\|.+\|[ \t]*(?:\r?\n|$))+)/gm, (match) => {
1236
+ const rows = match.trim().split(/\r?\n/).filter((line) => line.trim());
1237
+ if (rows.length < 2) return match;
1238
+ const isSeparatorRow = /^\|[\s\-:|]+\|$/.test(rows[1].trim());
1239
+ if (!isSeparatorRow) return match;
1240
+ const parseCells = (row) => row.split("|").slice(1, -1).map((cell) => cell.trim());
1241
+ const headerCells = parseCells(rows[0]).map(
1242
+ (cell) => `<th class="px-3 py-2 text-left font-medium text-xs uppercase tracking-wide border-b border-border">${cell}</th>`
1243
+ ).join("");
1244
+ const bodyRows = rows.slice(2).map(
1245
+ (row) => `<tr class="border-b border-border last:border-0 hover:bg-muted/50">${parseCells(row).map((cell) => `<td class="px-3 py-2 text-sm">${cell}</td>`).join("")}</tr>`
1246
+ ).join("");
1247
+ return `<div class="overflow-x-auto my-3 rounded-[var(--radius)] border border-border"><table class="w-full text-sm"><thead class="bg-muted/50"><tr>${headerCells}</tr></thead><tbody>${bodyRows}</tbody></table></div>`;
1248
+ });
1249
+ html = html.replace(/\n\n/g, '</p><p class="mb-2 break-words">');
1250
+ html = html.replace(/\n/g, "<br/>");
1251
+ html = '<p class="mb-2 break-words">' + html + "</p>";
1252
+ html = html.replace(/<p[^>]*>\s*<\/p>/g, "");
1253
+ return html;
1254
+ };
1255
+ const htmlContent = convertMarkdownToHtml(content);
1256
+ return /* @__PURE__ */ jsxRuntime.jsx(
1257
+ "div",
1258
+ {
1259
+ className: `text-sm leading-relaxed break-words overflow-wrap-anywhere max-w-full ${className}`,
1260
+ dangerouslySetInnerHTML: { __html: htmlContent }
1261
+ }
1262
+ );
1263
+ }
1264
+
1265
+ function FormattedDocument({
1266
+ content,
1267
+ maxPreviewLength = 500,
1268
+ className = ""
1269
+ }) {
1270
+ const [isExpanded, setIsExpanded] = React.useState(false);
1271
+ const { t } = reactI18next.useTranslation();
1272
+ const convertMarkdownToHtml = (markdown) => {
1273
+ let html = markdown;
1274
+ html = html.replace(
1275
+ /^### (.*$)/gim,
1276
+ '<h3 class="text-base font-medium mt-2 mb-1 text-foreground">$1</h3>'
1277
+ );
1278
+ html = html.replace(
1279
+ /^## (.*$)/gim,
1280
+ '<h2 class="text-lg font-medium mt-2 mb-1 text-foreground">$1</h2>'
1281
+ );
1282
+ html = html.replace(
1283
+ /^# (.*$)/gim,
1284
+ '<h1 class="text-xl font-medium mt-3 mb-2 text-foreground">$1</h1>'
1285
+ );
1286
+ html = html.replace(
1287
+ /\*\*(.*?)\*\*/g,
1288
+ '<strong class="font-medium text-foreground">$1</strong>'
1289
+ );
1290
+ html = html.replace(/\*(.*?)\*/g, '<em class="italic">$1</em>');
1291
+ html = html.replace(
1292
+ /^[-*+] \[ \] (.*$)/gim,
1293
+ '<div class="flex items-center gap-2 ml-4 my-0.5"><input type="checkbox" disabled class="rounded w-3.5 h-3.5 accent-primary" aria-label="$1" /> <span class="text-sm">$1</span></div>'
1294
+ );
1295
+ html = html.replace(
1296
+ /^[-*+] \[x\] (.*$)/gim,
1297
+ '<div class="flex items-center gap-2 ml-4 my-0.5"><input type="checkbox" checked disabled class="rounded w-3.5 h-3.5 accent-primary" aria-label="$1" /> <span class="text-sm">$1</span></div>'
1298
+ );
1299
+ html = html.replace(/((?:^[-*+] .*$(?:\n|$))+)/gim, (match) => {
1300
+ const items = match.trim().split("\n").map((item) => `<li class="ml-6 my-0.5 list-disc">${item.replace(/^[-*+] /i, "")}</li>`).join("");
1301
+ return `<ul class="list-disc my-2">${items}</ul>`;
1302
+ });
1303
+ html = html.replace(/((?:^\d+\. .*$(?:\n|$))+)/gim, (match) => {
1304
+ const items = match.trim().split("\n").map((item) => `<li class="ml-6 my-0.5 list-decimal">${item.replace(/^\d+\. /i, "")}</li>`).join("");
1305
+ return `<ol class="list-decimal my-2">${items}</ol>`;
1306
+ });
1307
+ html = html.replace(/^---$/gim, '<hr class="my-2 border-border" />');
1308
+ html = html.replace(/\n\n+/g, '</p><p class="my-0.5">');
1309
+ html = html.replace(/\n/g, " ");
1310
+ html = '<p class="my-0.5">' + html + "</p>";
1311
+ return html;
1312
+ };
1313
+ const htmlContent = convertMarkdownToHtml(content);
1314
+ const isLong = content.length > maxPreviewLength;
1315
+ const displayContent = !isLong || isExpanded ? htmlContent : convertMarkdownToHtml(content.substring(0, maxPreviewLength) + "...");
1316
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
1317
+ /* @__PURE__ */ jsxRuntime.jsx(
1318
+ "div",
1319
+ {
1320
+ className: "max-w-none text-sm text-foreground leading-relaxed break-words overflow-hidden",
1321
+ dangerouslySetInnerHTML: { __html: displayContent }
1322
+ }
1323
+ ),
1324
+ isLong && /* @__PURE__ */ jsxRuntime.jsx(
1325
+ button.Button,
1326
+ {
1327
+ variant: "ghost",
1328
+ size: "sm",
1329
+ onClick: () => setIsExpanded(!isExpanded),
1330
+ className: "mt-2 w-full text-xs hover:bg-accent text-muted-foreground",
1331
+ children: isExpanded ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1332
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "w-3 h-3 mr-1" }),
1333
+ t("common.seeLess")
1334
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1335
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-3 h-3 mr-1" }),
1336
+ t("common.seeMore")
1337
+ ] })
1338
+ }
1339
+ )
1340
+ ] });
1341
+ }
1342
+
1343
+ function AssistantMessageBubble({
1344
+ msg,
1345
+ copiedId,
1346
+ generatingPodcastId,
1347
+ executingCommand,
1348
+ savedSearches,
1349
+ enablePodcastGeneration,
1350
+ feedbackOptions,
1351
+ onCopyMessage,
1352
+ onToggleFavorite,
1353
+ onGeneratePodcast,
1354
+ onDownloadDocument,
1355
+ onDownloadPodcast,
1356
+ onEditDocument,
1357
+ onOpenSearchResult,
1358
+ onExecuteSearchCommand,
1359
+ onEvaluationClick,
1360
+ onOpenFeedbackDialog
1361
+ }) {
1362
+ const { t, i18n } = reactI18next.useTranslation();
1363
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1364
+ framerMotion.motion.div,
1365
+ {
1366
+ initial: { opacity: 0, y: 10 },
1367
+ animate: { opacity: 1, y: 0 },
1368
+ className: `flex gap-2 w-full min-w-0 ${msg.type === "user" ? "justify-end" : "justify-start"}`,
1369
+ children: [
1370
+ msg.type === "assistant" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(XerticaOrbe.XerticaOrbe, { size: 32 }) }),
1371
+ /* @__PURE__ */ jsxRuntime.jsxs(
1372
+ "div",
1373
+ {
1374
+ className: button.cn(
1375
+ "flex flex-col min-w-0 transition-all duration-300",
1376
+ msg.type === "user" ? "max-w-[85%] md:max-w-[70%] items-end w-fit" : button.cn(
1377
+ "items-start",
1378
+ msg.tableData || msg.chartData || msg.searchResults || msg.attachmentType === "document" ? "w-full max-w-full" : "w-fit max-w-[95%] md:max-w-[90%]"
1379
+ )
1380
+ ),
1381
+ children: [
1382
+ /* @__PURE__ */ jsxRuntime.jsxs(
1383
+ "div",
1384
+ {
1385
+ className: button.cn(
1386
+ "px-4 py-2 break-words overflow-hidden overflow-x-hidden w-full min-w-0 rounded-2xl",
1387
+ msg.type === "user" ? "bg-primary text-primary-foreground shadow-sm" : "bg-muted text-foreground"
1388
+ ),
1389
+ children: [
1390
+ msg.attachmentType === "document" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2 pb-2 border-b border-border min-w-0 overflow-hidden", children: [
1391
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1 overflow-hidden", children: [
1392
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "w-4 h-4 flex-shrink-0" }),
1393
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium break-words", children: msg.attachmentName })
1394
+ ] }),
1395
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 flex-shrink-0", children: [
1396
+ /* @__PURE__ */ jsxRuntime.jsx(
1397
+ button.Button,
1398
+ {
1399
+ variant: "ghost",
1400
+ size: "sm",
1401
+ onClick: () => msg.documentContent && msg.attachmentName && onDownloadDocument(msg.documentContent, msg.attachmentName),
1402
+ className: "h-6 px-2",
1403
+ title: t("assistant.download"),
1404
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "w-3 h-3" })
1405
+ }
1406
+ ),
1407
+ /* @__PURE__ */ jsxRuntime.jsxs(
1408
+ button.Button,
1409
+ {
1410
+ variant: "ghost",
1411
+ size: "sm",
1412
+ onClick: () => msg.documentContent && msg.documentTitle && onEditDocument(msg.documentContent, msg.documentTitle),
1413
+ className: "h-6 px-2",
1414
+ children: [
1415
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Edit, { className: "w-3 h-3 mr-1" }),
1416
+ t("common.edit")
1417
+ ]
1418
+ }
1419
+ )
1420
+ ] })
1421
+ ] }),
1422
+ msg.attachmentType && msg.attachmentType !== "podcast" && msg.attachmentType !== "document" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-2 pb-2 border-b border-border min-w-0 overflow-hidden", children: [
1423
+ msg.attachmentType === "file" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "w-4 h-4 flex-shrink-0" }),
1424
+ msg.attachmentType === "audio" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Music, { className: "w-4 h-4 flex-shrink-0" }),
1425
+ msg.attachmentType === "image" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Image, { className: "w-4 h-4 flex-shrink-0" }),
1426
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-small break-words", children: msg.attachmentName })
1427
+ ] }),
1428
+ msg.type === "user" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap break-words", children: msg.content }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1429
+ (msg.content.includes("🔐") || msg.content.includes("❌")) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-3 p-3 border rounded-[var(--radius)] overflow-hidden bg-[var(--toast-error-bg)]/20 border-[var(--toast-error-border)]/30", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 min-w-0", children: [
1430
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "w-5 h-5 flex-shrink-0 mt-0.5 text-[var(--toast-error-icon)]" }),
1431
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(MarkdownMessage, { content: msg.content, className: "text-foreground" }) })
1432
+ ] }) }),
1433
+ !(msg.content.includes("🔐") || msg.content.includes("❌")) && /* @__PURE__ */ jsxRuntime.jsx(MarkdownMessage, { content: msg.content, className: "text-foreground" })
1434
+ ] }),
1435
+ msg.chartData && msg.chartConfig && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 w-full h-[300px] min-w-[300px]", children: /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.ChartContainer, { config: msg.chartConfig, className: "h-full w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive.BarChart, { accessibilityLayer: true, data: msg.chartData, children: [
1436
+ /* @__PURE__ */ jsxRuntime.jsx(RechartsPrimitive.CartesianGrid, { vertical: false }),
1437
+ /* @__PURE__ */ jsxRuntime.jsx(
1438
+ RechartsPrimitive.XAxis,
1439
+ {
1440
+ dataKey: "month",
1441
+ tickLine: false,
1442
+ tickMargin: 10,
1443
+ axisLine: false,
1444
+ tickFormatter: (value) => value.slice(0, 3)
1445
+ }
1446
+ ),
1447
+ /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.ChartTooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.ChartTooltipContent, {}) }),
1448
+ /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.ChartLegendContent, {}) }),
1449
+ Object.keys(msg.chartConfig).map((key) => /* @__PURE__ */ jsxRuntime.jsx(RechartsPrimitive.Bar, { dataKey: key, fill: `var(--color-${key})`, radius: 4 }, key))
1450
+ ] }) }) }),
1451
+ msg.tableData && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 w-full max-w-full border rounded-[var(--radius)] overflow-x-auto custom-scrollbar relative", children: /* @__PURE__ */ jsxRuntime.jsxs(richTextEditor.Table, { children: [
1452
+ msg.tableData.caption && /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.TableCaption, { children: msg.tableData.caption }),
1453
+ /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.TableRow, { children: msg.tableData.headers.map((header, i) => /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.TableHead, { children: header }, i)) }) }),
1454
+ /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.TableBody, { children: msg.tableData.rows.map((row, i) => /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.TableRow, { children: row.map((cell, j) => /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.TableCell, { children: cell }, j)) }, i)) })
1455
+ ] }) }),
1456
+ msg.attachmentType === "document" && msg.documentContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 pt-3 border-t border-border overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(FormattedDocument, { content: msg.documentContent, maxPreviewLength: 250 }) }),
1457
+ msg.attachmentType === "podcast" && msg.audioUrl && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 pt-3 border-t border-border overflow-hidden", children: [
1458
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3 min-w-0 overflow-hidden", children: [
1459
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1 overflow-hidden", children: [
1460
+ /* @__PURE__ */ jsxRuntime.jsx("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)]", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Radio, { className: "w-3 h-3 text-white" }) }),
1461
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium break-words", children: msg.attachmentName })
1462
+ ] }),
1463
+ /* @__PURE__ */ jsxRuntime.jsx(
1464
+ button.Button,
1465
+ {
1466
+ variant: "ghost",
1467
+ size: "sm",
1468
+ onClick: () => msg.audioUrl && msg.attachmentName && onDownloadPodcast(msg.audioUrl, msg.attachmentName),
1469
+ className: "h-6 px-2 flex-shrink-0",
1470
+ title: t("assistant.download"),
1471
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "w-3 h-3" })
1472
+ }
1473
+ )
1474
+ ] }),
1475
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-[var(--radius)] p-2 overflow-hidden bg-gradient-to-r from-[var(--chart-1)]/10 to-[var(--chart-4)]/10", children: /* @__PURE__ */ jsxRuntime.jsxs("audio", { controls: true, className: "w-full max-w-full h-10 outline-none", children: [
1476
+ /* @__PURE__ */ jsxRuntime.jsx("source", { src: msg.audioUrl, type: "audio/mpeg" }),
1477
+ t("assistant.audioNotSupported")
1478
+ ] }) })
1479
+ ] }),
1480
+ msg.attachmentType === "search" && msg.searchResults && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 pt-3 border-t border-border space-y-4 overflow-hidden", children: [
1481
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-hidden", children: [
1482
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
1483
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "w-4 h-4 text-[var(--chart-4)]" }),
1484
+ /* @__PURE__ */ jsxRuntime.jsxs("h4", { className: "text-foreground", children: [
1485
+ t("assistant.searchResultsFound"),
1486
+ " (",
1487
+ msg.searchResults.length,
1488
+ ")"
1489
+ ] })
1490
+ ] }),
1491
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2 overflow-hidden", children: msg.searchResults.map((result) => /* @__PURE__ */ jsxRuntime.jsx(
1492
+ "div",
1493
+ {
1494
+ onClick: () => onOpenSearchResult(result),
1495
+ className: "p-3 rounded-[var(--radius)] border border-border transition-all cursor-pointer group overflow-hidden hover:bg-muted/50",
1496
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-2 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 flex-1 min-w-0 overflow-hidden", children: [
1497
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-0.5 flex-shrink-0", children: [
1498
+ result.type === "document" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "w-4 h-4 text-[var(--chart-4)]" }),
1499
+ result.type === "project" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderOpen, { className: "w-4 h-4 text-[var(--chart-1)]" }),
1500
+ result.type === "conversation" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "w-4 h-4 text-[var(--chart-2)]" }),
1501
+ result.type === "file" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Folder, { className: "w-4 h-4 text-[var(--chart-3)]" }),
1502
+ result.type === "contact" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Users, { className: "w-4 h-4 text-[var(--chart-5)]" })
1503
+ ] }),
1504
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 overflow-hidden", children: [
1505
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 min-w-0", children: [
1506
+ /* @__PURE__ */ jsxRuntime.jsx("h5", { className: "text-sm font-medium break-words flex-1 min-w-0 text-foreground", children: result.title }),
1507
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-1.5 py-0.5 rounded-sm flex-shrink-0 self-start bg-[var(--chart-4)]/10 text-[var(--chart-4)]", children: [
1508
+ result.relevance,
1509
+ "%"
1510
+ ] })
1511
+ ] }),
1512
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1 line-clamp-2 break-words", children: result.description }),
1513
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mt-2 flex-wrap min-w-0", children: [
1514
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground flex items-center gap-1 min-w-0 max-w-full", children: [
1515
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3 h-3 flex-shrink-0" }),
1516
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: result.path })
1517
+ ] }),
1518
+ result.lastModified && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground flex items-center gap-1 flex-shrink-0", children: [
1519
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-3 h-3" }),
1520
+ result.lastModified
1521
+ ] })
1522
+ ] })
1523
+ ] })
1524
+ ] }) })
1525
+ },
1526
+ result.id
1527
+ )) })
1528
+ ] }),
1529
+ msg.searchSources && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1530
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "mb-2 text-foreground", children: t("assistant.searchSources") }),
1531
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 overflow-hidden", children: msg.searchSources.map((source, index) => /* @__PURE__ */ jsxRuntime.jsxs(
1532
+ "div",
1533
+ {
1534
+ className: "px-3 py-1.5 border max-w-full rounded-[var(--radius-button)] bg-muted border-border",
1535
+ children: [
1536
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-foreground break-words", children: source.name }),
1537
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground ml-1 whitespace-nowrap", children: [
1538
+ "(",
1539
+ source.count,
1540
+ ")"
1541
+ ] })
1542
+ ]
1543
+ },
1544
+ index
1545
+ )) })
1546
+ ] }),
1547
+ msg.searchCommands && msg.searchResults && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1548
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "mb-2 text-foreground", children: t("assistant.searchActions") }),
1549
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2", children: msg.searchCommands.map((command) => /* @__PURE__ */ jsxRuntime.jsxs(
1550
+ "button",
1551
+ {
1552
+ onClick: () => onExecuteSearchCommand(
1553
+ command.id,
1554
+ msg.content.replace("🔍 Pesquisa realizada com sucesso!", "").split('"')[1] || "pesquisa",
1555
+ msg.searchResults,
1556
+ msg.id
1557
+ ),
1558
+ disabled: executingCommand === command.id,
1559
+ className: button.cn(
1560
+ "flex items-start gap-2 p-2 rounded-[var(--radius)] border transition-all text-left disabled:opacity-50 disabled:cursor-not-allowed",
1561
+ savedSearches.includes(msg.id) && command.id === "5" ? "border-[var(--toast-warning-border)] bg-[var(--toast-warning-bg)]/20" : "border-border bg-transparent hover:bg-muted/50"
1562
+ ),
1563
+ children: [
1564
+ executingCommand === command.id ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "w-5 h-5 animate-spin flex-shrink-0 text-primary" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: command.icon }),
1565
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 overflow-hidden", children: [
1566
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-foreground break-words", children: command.id === "5" && savedSearches.includes(msg.id) ? `⭐ ${t("assistant.searchSaved")}` : command.label }),
1567
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground break-words", children: executingCommand === command.id ? t("assistant.processing") : command.description })
1568
+ ] })
1569
+ ]
1570
+ },
1571
+ command.id
1572
+ )) })
1573
+ ] })
1574
+ ] })
1575
+ ]
1576
+ }
1577
+ ),
1578
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1 px-2", children: [
1579
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: msg.timestamp.toLocaleTimeString(i18n.language, {
1580
+ hour: "2-digit",
1581
+ minute: "2-digit"
1582
+ }) }),
1583
+ enablePodcastGeneration && msg.type === "assistant" && msg.attachmentType !== "podcast" && /* @__PURE__ */ jsxRuntime.jsx(
1584
+ button.Button,
1585
+ {
1586
+ variant: "ghost",
1587
+ size: "sm",
1588
+ onClick: () => onGeneratePodcast(msg.id, msg.content),
1589
+ disabled: generatingPodcastId === msg.id,
1590
+ className: "h-6 w-6 p-0 disabled:opacity-50 text-muted-foreground",
1591
+ title: t("assistant.generatePodcast"),
1592
+ "aria-label": t("assistant.generatePodcast"),
1593
+ children: generatingPodcastId === msg.id ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "w-3 h-3 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Radio, { className: "w-3 h-3" })
1594
+ }
1595
+ ),
1596
+ msg.type === "assistant" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 border-l border-border pl-2 ml-1", children: [
1597
+ /* @__PURE__ */ jsxRuntime.jsx(
1598
+ button.Button,
1599
+ {
1600
+ variant: "ghost",
1601
+ size: "icon",
1602
+ className: button.cn(
1603
+ "h-6 w-6 rounded-full hover:bg-green-100 dark:hover:bg-green-900/20 hover:text-green-600",
1604
+ msg.evaluation === "like" && "text-green-600 bg-green-100 dark:bg-green-900/20"
1605
+ ),
1606
+ onClick: () => onEvaluationClick(msg.id, "like"),
1607
+ title: t("assistant.like"),
1608
+ "aria-label": t("assistant.like"),
1609
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ThumbsUp, { className: "h-3.5 w-3.5" })
1610
+ }
1611
+ ),
1612
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenu, { children: [
1613
+ /* @__PURE__ */ jsxRuntime.jsx(dropdownMenu.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1614
+ button.Button,
1615
+ {
1616
+ variant: "ghost",
1617
+ size: "icon",
1618
+ className: button.cn(
1619
+ "h-6 w-6 rounded-full hover:bg-red-100 dark:hover:bg-red-900/20 hover:text-red-600",
1620
+ msg.evaluation === "dislike" && "text-red-600 bg-red-100 dark:bg-red-900/20"
1621
+ ),
1622
+ title: t("assistant.dislike"),
1623
+ "aria-label": t("assistant.dislike"),
1624
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ThumbsDown, { className: "h-3.5 w-3.5" })
1625
+ }
1626
+ ) }),
1627
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenuContent, { align: "start", children: [
1628
+ feedbackOptions && feedbackOptions.length > 0 ? feedbackOptions.map((option, idx) => /* @__PURE__ */ jsxRuntime.jsx(
1629
+ dropdownMenu.DropdownMenuItem,
1630
+ {
1631
+ onClick: () => onOpenFeedbackDialog(msg.id, option),
1632
+ children: option
1633
+ },
1634
+ idx
1635
+ )) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1636
+ /* @__PURE__ */ jsxRuntime.jsx(
1637
+ dropdownMenu.DropdownMenuItem,
1638
+ {
1639
+ onClick: () => onOpenFeedbackDialog(msg.id, t("assistant.feedback.notWhatIWanted")),
1640
+ children: t("assistant.feedback.notWhatIWanted")
1641
+ }
1642
+ ),
1643
+ /* @__PURE__ */ jsxRuntime.jsx(
1644
+ dropdownMenu.DropdownMenuItem,
1645
+ {
1646
+ onClick: () => onOpenFeedbackDialog(msg.id, t("assistant.feedback.incorrectInfo")),
1647
+ children: t("assistant.feedback.incorrectInfo")
1648
+ }
1649
+ ),
1650
+ /* @__PURE__ */ jsxRuntime.jsx(
1651
+ dropdownMenu.DropdownMenuItem,
1652
+ {
1653
+ onClick: () => onOpenFeedbackDialog(msg.id, t("assistant.feedback.incompleteAnswer")),
1654
+ children: t("assistant.feedback.incompleteAnswer")
1655
+ }
1656
+ )
1657
+ ] }),
1658
+ /* @__PURE__ */ jsxRuntime.jsx(dropdownMenu.DropdownMenuItem, { onClick: () => onOpenFeedbackDialog(msg.id, null), children: t("assistant.feedback.other") })
1659
+ ] })
1660
+ ] })
1661
+ ] }),
1662
+ /* @__PURE__ */ jsxRuntime.jsx(
1663
+ button.Button,
1664
+ {
1665
+ variant: "ghost",
1666
+ size: "sm",
1667
+ onClick: () => onCopyMessage(msg.content, msg.id),
1668
+ className: `h-6 w-6 p-0 ${copiedId === msg.id ? "text-[var(--toast-success-icon)]" : "text-muted-foreground"}`,
1669
+ "aria-label": copiedId === msg.id ? t("assistant.copied") : t("assistant.copyMessage"),
1670
+ children: copiedId === msg.id ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-3 h-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "w-3 h-3" })
1671
+ }
1672
+ )
1673
+ ] })
1674
+ ]
1675
+ }
1676
+ )
1677
+ ]
1678
+ },
1679
+ msg.id
1680
+ );
1681
+ }
1682
+
1683
+ function AssistantTypingIndicator() {
1684
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1685
+ framerMotion.motion.div,
1686
+ {
1687
+ initial: { opacity: 0, y: 10 },
1688
+ animate: { opacity: 1, y: 0 },
1689
+ className: "flex gap-2 justify-start",
1690
+ children: [
1691
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(XerticaOrbe.XerticaOrbe, { size: 32 }) }),
1692
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-3 bg-muted rounded-2xl", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1", children: [
1693
+ /* @__PURE__ */ jsxRuntime.jsx(
1694
+ framerMotion.motion.div,
1695
+ {
1696
+ className: "w-2 h-2 rounded-full bg-muted-foreground",
1697
+ animate: { y: [0, -8, 0] },
1698
+ transition: { repeat: Infinity, duration: 0.6, delay: 0 }
1699
+ }
1700
+ ),
1701
+ /* @__PURE__ */ jsxRuntime.jsx(
1702
+ framerMotion.motion.div,
1703
+ {
1704
+ className: "w-2 h-2 rounded-full bg-muted-foreground",
1705
+ animate: { y: [0, -8, 0] },
1706
+ transition: { repeat: Infinity, duration: 0.6, delay: 0.2 }
1707
+ }
1708
+ ),
1709
+ /* @__PURE__ */ jsxRuntime.jsx(
1710
+ framerMotion.motion.div,
1711
+ {
1712
+ className: "w-2 h-2 rounded-full bg-muted-foreground",
1713
+ animate: { y: [0, -8, 0] },
1714
+ transition: { repeat: Infinity, duration: 0.6, delay: 0.4 }
1715
+ }
1716
+ )
1717
+ ] }) })
1718
+ ]
1719
+ }
1720
+ );
1721
+ }
1722
+
1723
+ function AssistantConversationList({
1724
+ conversations,
1725
+ currentConversationId,
1726
+ activeTab,
1727
+ isFullPage,
1728
+ onNewConversation,
1729
+ onSelectConversation,
1730
+ onToggleFavorite
1731
+ }) {
1732
+ const { t } = reactI18next.useTranslation();
1733
+ return /* @__PURE__ */ jsxRuntime.jsx(input.ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `p-4 ${isFullPage ? "mx-auto w-full max-w-6xl" : ""}`, children: [
1734
+ /* @__PURE__ */ jsxRuntime.jsxs(
1735
+ button.Button,
1736
+ {
1737
+ variant: "outline",
1738
+ size: "sm",
1739
+ onClick: onNewConversation,
1740
+ className: "w-full mb-4 justify-start",
1741
+ children: [
1742
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "w-4 h-4 mr-2" }),
1743
+ t("assistant.newConversation")
1744
+ ]
1745
+ }
1746
+ ),
1747
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: conversations.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-8", children: [
1748
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heart, { className: "w-12 h-12 mx-auto text-muted-foreground/50 mb-2" }),
1749
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: activeTab === "favoritos" ? t("assistant.noFavorites") : t("assistant.noHistory") })
1750
+ ] }) : conversations.map((conversa) => /* @__PURE__ */ jsxRuntime.jsxs(
1751
+ "div",
1752
+ {
1753
+ onClick: () => onSelectConversation(conversa.id),
1754
+ className: button.cn(
1755
+ "p-3 rounded-[var(--radius)] cursor-pointer transition-colors duration-200 border",
1756
+ conversa.id === currentConversationId ? "border-primary bg-primary/10" : "border-border hover:bg-muted"
1757
+ ),
1758
+ children: [
1759
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between mb-1", children: [
1760
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-medium text-foreground truncate flex-1", children: conversa.title }),
1761
+ /* @__PURE__ */ jsxRuntime.jsx(
1762
+ button.Button,
1763
+ {
1764
+ variant: "ghost",
1765
+ size: "sm",
1766
+ onClick: (e) => {
1767
+ e.stopPropagation();
1768
+ onToggleFavorite(conversa.id);
1769
+ },
1770
+ className: "h-6 w-6 p-0 flex-shrink-0 ml-1",
1771
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1772
+ lucideReact.Heart,
1773
+ {
1774
+ className: button.cn(
1775
+ "w-3 h-3",
1776
+ conversa.isFavorite ? "text-destructive fill-current" : "text-muted-foreground"
1777
+ )
1778
+ }
1779
+ )
1780
+ }
1781
+ )
1782
+ ] }),
1783
+ conversa.lastMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground truncate mb-1", children: conversa.lastMessage }),
1784
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: conversa.timestamp })
1785
+ ]
1786
+ },
1787
+ conversa.id
1788
+ )) })
1789
+ ] }) });
1790
+ }
1791
+
1792
+ function AssistantFeedbackDialog({
1793
+ state,
1794
+ onReasonChange,
1795
+ onClose,
1796
+ onSubmit
1797
+ }) {
1798
+ const { t } = reactI18next.useTranslation();
1799
+ return /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.Dialog, { open: state.isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(richTextEditor.DialogContent, { className: "sm:max-w-[600px]", children: [
1800
+ /* @__PURE__ */ jsxRuntime.jsxs(richTextEditor.DialogHeader, { children: [
1801
+ /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.DialogTitle, { className: "pr-8", children: state.category ? t("assistant.feedbackDialog.titleWithCategory", { category: state.category }) : t("assistant.feedbackDialog.title") }),
1802
+ /* @__PURE__ */ jsxRuntime.jsx(richTextEditor.DialogDescription, { children: state.category ? t("assistant.feedbackDialog.descriptionOptional") : t("assistant.feedbackDialog.description") })
1803
+ ] }),
1804
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-4 py-4 px-6", children: /* @__PURE__ */ jsxRuntime.jsx(
1805
+ richTextEditor.Textarea,
1806
+ {
1807
+ className: "min-h-[100px]",
1808
+ placeholder: state.category ? t("assistant.feedbackDialog.placeholderOptional") : t("assistant.feedbackDialog.placeholder"),
1809
+ "aria-label": state.category ? t("assistant.feedbackDialog.placeholderOptional") : t("assistant.feedbackDialog.placeholder"),
1810
+ value: state.reason,
1811
+ onChange: (e) => onReasonChange(e.target.value),
1812
+ rows: 4
1813
+ }
1814
+ ) }),
1815
+ /* @__PURE__ */ jsxRuntime.jsxs(richTextEditor.DialogFooter, { children: [
1816
+ /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "outline", onClick: onClose, children: t("common.cancel") }),
1817
+ /* @__PURE__ */ jsxRuntime.jsx(button.Button, { onClick: onSubmit, disabled: !state.category && !state.reason.trim(), children: state.category ? t("assistant.feedbackDialog.confirmAndSend") : t("assistant.feedbackDialog.send") })
1818
+ ] })
1819
+ ] }) });
1820
+ }
1821
+
1822
+ function AssistantDocumentEditor({
1823
+ document,
1824
+ isMobile,
1825
+ containerWidth,
1826
+ onClose,
1827
+ onChange
1828
+ }) {
1829
+ const { t } = reactI18next.useTranslation();
1830
+ return /* @__PURE__ */ jsxRuntime.jsx(
1831
+ "div",
1832
+ {
1833
+ className: button.cn(
1834
+ "flex flex-col border-border bg-background overflow-hidden transition-all duration-300",
1835
+ isMobile ? "fixed inset-0 z-[110] w-full h-[100dvh]" : "absolute top-0 bottom-0 right-full w-[800px] border-l border-r border-border shadow-[-25px_0_50px_-15px_rgba(0,0,0,0.15)] z-[90]"
1836
+ ),
1837
+ style: { maxWidth: isMobile ? "none" : `calc(100vw - ${containerWidth})` },
1838
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col", children: [
1839
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 h-[64px] border-b border-border bg-card flex items-center justify-between", children: [
1840
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
1841
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 bg-primary/10 rounded-md", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "w-4 h-4 text-primary" }) }),
1842
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-card-foreground text-sm", children: document.title })
1843
+ ] }),
1844
+ /* @__PURE__ */ jsxRuntime.jsx(
1845
+ button.Button,
1846
+ {
1847
+ variant: "ghost",
1848
+ size: "icon",
1849
+ className: "h-8 w-8 rounded-full",
1850
+ onClick: onClose,
1851
+ "aria-label": t("assistant.closeDocumentEditor"),
1852
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4" })
1853
+ }
1854
+ )
1855
+ ] }),
1856
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 bg-muted/20 p-0 sm:p-6 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
1857
+ richTextEditor.RichTextEditor,
1858
+ {
1859
+ value: document.content || "",
1860
+ onChange: (newVal) => onChange({ ...document, content: newVal }),
1861
+ placeholder: t("assistant.documentEditorPlaceholder"),
1862
+ className: "max-w-4xl mx-auto h-full",
1863
+ actionButton: /* @__PURE__ */ jsxRuntime.jsxs(button.Button, { size: "sm", className: "gap-2 h-8", children: [
1864
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-3.5 h-3.5" }),
1865
+ t("common.save")
1866
+ ] })
1867
+ }
1868
+ ) })
1869
+ ] })
1870
+ }
1871
+ );
1872
+ }
1873
+
1874
+ function XerticaAssistant({
1875
+ mode = "expanded",
1876
+ isExpanded: controlledIsExpanded,
1877
+ onToggle,
1878
+ defaultTab = "chat",
1879
+ demoMode = true,
1880
+ onNavigateSettings,
1881
+ onNavigateFullPage,
1882
+ userName,
1883
+ initialMessages = [],
1884
+ savedConversations = [],
1885
+ suggestions: propSuggestions,
1886
+ onSendMessage,
1887
+ onFileAttach,
1888
+ isProcessing = false,
1889
+ width,
1890
+ height,
1891
+ className = "",
1892
+ mobileFloating = false,
1893
+ customResponses = [],
1894
+ responseGenerator,
1895
+ richSuggestions = [],
1896
+ welcomeMessage,
1897
+ onRichAction,
1898
+ onEvaluation,
1899
+ feedbackOptions,
1900
+ // Feature flags — all default to true for backward compatibility
1901
+ showHistory = true,
1902
+ showFavorites = true,
1903
+ enableAudioInput = true,
1904
+ enableFileAttachment = true,
1905
+ enableDocumentCreation = true,
1906
+ enablePodcastGeneration = true,
1907
+ enableSearch = true
1908
+ }) {
1909
+ const { t } = reactI18next.useTranslation();
1910
+ const resolvedUserName = userName ?? t("assistant.defaultUserName");
1911
+ const resolvedWelcomeMessage = welcomeMessage ?? t("assistant.defaultWelcomeMessage");
1912
+ const {
1913
+ isFullPage,
1914
+ isExpanded,
1915
+ isMobile,
1916
+ abaSelecionada,
1917
+ setAbaSelecionada,
1918
+ mensagens,
1919
+ mensagem,
1920
+ setMensagem,
1921
+ conversaAtual,
1922
+ conversasFiltradas,
1923
+ copiedId,
1924
+ generatingPodcastId,
1925
+ executingCommand,
1926
+ savedSearches,
1927
+ editingDocument,
1928
+ setEditingDocument,
1929
+ showMoreSuggestions,
1930
+ setShowMoreSuggestions,
1931
+ evaluationState,
1932
+ setEvaluationState,
1933
+ sugestoes,
1934
+ messagesEndRef,
1935
+ fileInputRef,
1936
+ audioInputRef,
1937
+ handleToggle,
1938
+ handleExpandWithTab,
1939
+ handleEnviarMensagem,
1940
+ handleToggleFavorite,
1941
+ handleCopyMessage,
1942
+ handleGeneratePodcast,
1943
+ handleDownloadDocument,
1944
+ handleDownloadPodcast,
1945
+ handleEditDocument,
1946
+ handleNovaConversa,
1947
+ handleSelecionarConversa,
1948
+ handleToggleFavoritaConversa,
1949
+ handleOpenSearchResult,
1950
+ handleExecuteSearchCommand,
1951
+ handleRichSuggestionClick,
1952
+ handleEvaluationClick,
1953
+ openFeedbackDialog,
1954
+ handleSubmitDislike
1955
+ } = useAssistant({
1956
+ mode,
1957
+ isExpanded: controlledIsExpanded,
1958
+ onToggle,
1959
+ defaultTab,
1960
+ demoMode,
1961
+ customResponses,
1962
+ initialMessages,
1963
+ savedConversations,
1964
+ suggestions: propSuggestions,
1965
+ onSendMessage,
1966
+ isProcessing,
1967
+ responseGenerator,
1968
+ richSuggestions,
1969
+ onRichAction,
1970
+ onEvaluation
1971
+ });
1972
+ const containerWidth = width ?? (isFullPage ? "100%" : isExpanded ? "420px" : "80px");
1973
+ const containerHeight = height ?? "h-full";
1974
+ if (isMobile && !isExpanded) {
1975
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1976
+ button.Button,
1977
+ {
1978
+ onClick: handleToggle,
1979
+ className: button.cn(
1980
+ "fixed bottom-4 right-4 h-14 rounded-full shadow-lg pl-3 pr-5 gap-3 bg-white text-zinc-900 hover:bg-zinc-50 border border-zinc-200 z-50 transition-all duration-300",
1981
+ className
1982
+ ),
1983
+ children: [
1984
+ /* @__PURE__ */ jsxRuntime.jsx(XerticaOrbe.XerticaOrbe, { size: 32 }),
1985
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-base tracking-wide", children: t("assistant.title") })
1986
+ ]
1987
+ }
1988
+ );
1989
+ }
1990
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1991
+ /* @__PURE__ */ jsxRuntime.jsx(
1992
+ "input",
1993
+ {
1994
+ ref: fileInputRef,
1995
+ type: "file",
1996
+ accept: ".pdf,.doc,.docx,.txt,.md",
1997
+ className: "hidden",
1998
+ onChange: (e) => {
1999
+ const file = e.target.files?.[0];
2000
+ if (file && onFileAttach) {
2001
+ onFileAttach(file);
2002
+ }
2003
+ },
2004
+ "aria-label": t("assistant.uploadDocument")
2005
+ }
2006
+ ),
2007
+ /* @__PURE__ */ jsxRuntime.jsx(
2008
+ "input",
2009
+ {
2010
+ ref: audioInputRef,
2011
+ type: "file",
2012
+ accept: "audio/*",
2013
+ className: "hidden",
2014
+ onChange: (e) => {
2015
+ const file = e.target.files?.[0];
2016
+ if (file && onFileAttach) {
2017
+ onFileAttach(file);
2018
+ }
2019
+ },
2020
+ "aria-label": t("assistant.uploadAudio")
2021
+ }
2022
+ ),
2023
+ /* @__PURE__ */ jsxRuntime.jsxs(
2024
+ "div",
2025
+ {
2026
+ className: button.cn(
2027
+ `${containerHeight} flex flex-col bg-background relative`,
2028
+ !isFullPage && "border-l border-border shadow-sm",
2029
+ isMobile && isExpanded && "fixed inset-0 z-[100] h-[100dvh] w-full border-l-0 shadow-2xl",
2030
+ className
2031
+ ),
2032
+ style: !(isMobile && isExpanded) ? {
2033
+ width: isFullPage ? "100%" : containerWidth
2034
+ } : void 0,
2035
+ children: [
2036
+ editingDocument && !isFullPage && /* @__PURE__ */ jsxRuntime.jsx(
2037
+ AssistantDocumentEditor,
2038
+ {
2039
+ document: editingDocument,
2040
+ isMobile,
2041
+ containerWidth,
2042
+ onClose: () => setEditingDocument(null),
2043
+ onChange: (doc) => setEditingDocument(doc)
2044
+ }
2045
+ ),
2046
+ !isFullPage && /* @__PURE__ */ jsxRuntime.jsx(
2047
+ AssistantHeader,
2048
+ {
2049
+ isExpanded,
2050
+ onToggle: handleToggle,
2051
+ onNavigateFullPage
2052
+ }
2053
+ ),
2054
+ !isExpanded && !isFullPage && /* @__PURE__ */ jsxRuntime.jsx(
2055
+ AssistantCollapsedView,
2056
+ {
2057
+ showHistory,
2058
+ showFavorites,
2059
+ onToggle: handleToggle,
2060
+ onExpandWithTab: handleExpandWithTab
2061
+ }
2062
+ ),
2063
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: (isExpanded || isFullPage) && /* @__PURE__ */ jsxRuntime.jsxs(
2064
+ framerMotion.motion.div,
2065
+ {
2066
+ initial: isFullPage ? false : { opacity: 0, x: 50 },
2067
+ animate: { opacity: 1, x: 0 },
2068
+ exit: isFullPage ? void 0 : { opacity: 0, x: 50 },
2069
+ transition: { duration: 0.2 },
2070
+ className: "flex-1 flex flex-col overflow-hidden",
2071
+ children: [
2072
+ !isFullPage && (showHistory || showFavorites) && /* @__PURE__ */ jsxRuntime.jsx(
2073
+ AssistantTabBar,
2074
+ {
2075
+ activeTab: abaSelecionada,
2076
+ showHistory,
2077
+ showFavorites,
2078
+ onTabChange: setAbaSelecionada
2079
+ }
2080
+ ),
2081
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
2082
+ abaSelecionada === "chat" && /* @__PURE__ */ jsxRuntime.jsx(
2083
+ "div",
2084
+ {
2085
+ className: `flex-1 flex flex-col min-h-0 ${isFullPage ? "mx-auto w-full max-w-6xl" : ""}`,
2086
+ children: mensagens.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
2087
+ AssistantWelcomeScreen,
2088
+ {
2089
+ userName: resolvedUserName,
2090
+ welcomeMessage: resolvedWelcomeMessage,
2091
+ suggestions: sugestoes,
2092
+ richSuggestions,
2093
+ showMoreSuggestions,
2094
+ onSetShowMoreSuggestions: setShowMoreSuggestions,
2095
+ onSendSuggestion: handleEnviarMensagem,
2096
+ onRichSuggestionClick: handleRichSuggestionClick
2097
+ }
2098
+ ) : /* @__PURE__ */ jsxRuntime.jsx(input.ScrollArea, { className: "flex-1 min-h-0 overflow-x-hidden [&_[data-radix-scroll-area-viewport]>div]:!block", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 px-4 py-4 max-w-6xl mx-auto !block !w-full", children: [
2099
+ mensagens.map((msg) => /* @__PURE__ */ jsxRuntime.jsx(
2100
+ AssistantMessageBubble,
2101
+ {
2102
+ msg,
2103
+ copiedId,
2104
+ generatingPodcastId,
2105
+ executingCommand,
2106
+ savedSearches,
2107
+ enablePodcastGeneration,
2108
+ feedbackOptions,
2109
+ onCopyMessage: handleCopyMessage,
2110
+ onToggleFavorite: handleToggleFavorite,
2111
+ onGeneratePodcast: handleGeneratePodcast,
2112
+ onDownloadDocument: handleDownloadDocument,
2113
+ onDownloadPodcast: handleDownloadPodcast,
2114
+ onEditDocument: handleEditDocument,
2115
+ onOpenSearchResult: handleOpenSearchResult,
2116
+ onExecuteSearchCommand: handleExecuteSearchCommand,
2117
+ onEvaluationClick: handleEvaluationClick,
2118
+ onOpenFeedbackDialog: openFeedbackDialog
2119
+ },
2120
+ msg.id
2121
+ )),
2122
+ isProcessing && /* @__PURE__ */ jsxRuntime.jsx(AssistantTypingIndicator, {}),
2123
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
2124
+ ] }) })
2125
+ }
2126
+ ),
2127
+ (abaSelecionada === "historico" && showHistory || abaSelecionada === "favoritos" && showFavorites) && /* @__PURE__ */ jsxRuntime.jsx(
2128
+ AssistantConversationList,
2129
+ {
2130
+ conversations: conversasFiltradas,
2131
+ currentConversationId: conversaAtual,
2132
+ activeTab: abaSelecionada,
2133
+ isFullPage,
2134
+ onNewConversation: handleNovaConversa,
2135
+ onSelectConversation: handleSelecionarConversa,
2136
+ onToggleFavorite: handleToggleFavoritaConversa
2137
+ }
2138
+ )
2139
+ ] }),
2140
+ abaSelecionada === "chat" && /* @__PURE__ */ jsxRuntime.jsx(
2141
+ ModernChatInput,
2142
+ {
2143
+ value: mensagem,
2144
+ onChange: setMensagem,
2145
+ onSubmit: handleEnviarMensagem,
2146
+ onFileUpload: enableFileAttachment ? () => fileInputRef.current?.click() : void 0,
2147
+ onAudioUpload: enableAudioInput ? () => audioInputRef.current?.click() : void 0,
2148
+ disabled: isProcessing,
2149
+ isFullPage,
2150
+ enableAudioInput,
2151
+ enableFileAttachment,
2152
+ enableDocumentCreation,
2153
+ enablePodcastGeneration,
2154
+ enableSearch
2155
+ }
2156
+ )
2157
+ ]
2158
+ }
2159
+ ) })
2160
+ ]
2161
+ }
2162
+ ),
2163
+ /* @__PURE__ */ jsxRuntime.jsx(
2164
+ AssistantFeedbackDialog,
2165
+ {
2166
+ state: evaluationState,
2167
+ onReasonChange: (reason) => setEvaluationState((prev) => ({ ...prev, reason })),
2168
+ onClose: () => setEvaluationState((prev) => ({ ...prev, isOpen: false })),
2169
+ onSubmit: handleSubmitDislike
2170
+ }
2171
+ )
2172
+ ] });
2173
+ }
2174
+
2175
+ exports.FormattedDocument = FormattedDocument;
2176
+ exports.MarkdownMessage = MarkdownMessage;
2177
+ exports.ModernChatInput = ModernChatInput;
2178
+ exports.XerticaAssistant = XerticaAssistant;
2179
+ exports.gerarResposta = gerarResposta;
2180
+ exports.useAssistant = useAssistant;