xertica-ui 2.5.0 → 2.5.2
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.
- package/CHANGELOG.md +35 -0
- package/README.md +56 -17
- package/assets/xertica-logo.svg +37 -37
- package/assets/xertica-x-logo.svg +20 -20
- package/bin/cli.ts +14 -2
- package/bin/generate-tokens.ts +262 -262
- package/bin/language-config.ts +359 -358
- package/components/assistant/code-block/CodeBlock.tsx +268 -268
- package/components/assistant/formatted-document/FormattedDocument.tsx +147 -147
- package/components/assistant/modern-chat-input/ModernChatInput.tsx +564 -564
- package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +99 -99
- package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -104
- package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -81
- package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +88 -88
- package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +75 -75
- package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +564 -564
- package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +67 -67
- package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +103 -103
- package/components/assistant/xertica-assistant/use-assistant.ts +615 -615
- package/components/assistant/xertica-assistant/xertica-assistant.tsx +611 -611
- package/components/blocks/card-patterns/ActivityCard.tsx +100 -100
- package/components/blocks/card-patterns/ActivityCardSkeleton.tsx +56 -56
- package/components/blocks/card-patterns/FeatureCardSkeleton.tsx +58 -58
- package/components/blocks/card-patterns/NotificationCard.tsx +140 -140
- package/components/blocks/card-patterns/NotificationCardSkeleton.tsx +81 -81
- package/components/blocks/card-patterns/ProfileCard.tsx +112 -112
- package/components/blocks/card-patterns/ProfileCardSkeleton.tsx +69 -69
- package/components/blocks/card-patterns/ProjectCard.tsx +123 -123
- package/components/blocks/card-patterns/ProjectCardSkeleton.tsx +67 -67
- package/components/blocks/card-patterns/QuickActionCardSkeleton.tsx +44 -44
- package/components/blocks/card-patterns/card-patterns.stories.tsx +594 -594
- package/components/blocks/card-patterns/index.ts +29 -29
- package/components/brand/language-selector/LanguageSelector.tsx +102 -102
- package/components/brand/language-selector/language-selector.stories.tsx +111 -111
- package/components/brand/language-selector/language-selector.test.tsx +101 -101
- package/components/brand/theme-toggle/ThemeToggle.tsx +74 -74
- package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
- package/components/index.ts +86 -86
- package/components/layout/sidebar/sidebar.mdx +1 -1
- package/components/layout/sidebar/sidebar.stories.tsx +1033 -787
- package/components/layout/sidebar/sidebar.tsx +338 -1
- package/components/media/FloatingMediaWrapper.tsx +371 -371
- package/components/media/audio-player/AudioPlayer.tsx +768 -768
- package/components/media/video-player/VideoPlayer.tsx +310 -310
- package/components/pages/home-content/HomeContent.tsx +120 -120
- package/components/pages/home-content/home-content.mdx +62 -62
- package/components/pages/home-page/HomePage.tsx +78 -78
- package/components/pages/home-page/home-page.mdx +53 -53
- package/components/pages/template-content/TemplateContent.tsx +1354 -1354
- package/components/pages/template-content/template-content.mdx +61 -61
- package/components/pages/template-page/TemplatePage.stories.tsx +32 -32
- package/components/pages/template-page/template-page.mdx +53 -53
- package/components/shared/error-boundary.stories.tsx +114 -114
- package/components/shared/error-boundary.tsx +150 -150
- package/components/shared/error-fallbacks.tsx +222 -222
- package/components/ui/accordion/accordion.mdx +8 -8
- package/components/ui/alert/alert.mdx +8 -8
- package/components/ui/alert-dialog/alert-dialog.mdx +8 -8
- package/components/ui/aspect-ratio/aspect-ratio.mdx +8 -8
- package/components/ui/assistant-chart/assistant-chart.mdx +8 -8
- package/components/ui/avatar/avatar.mdx +8 -8
- package/components/ui/badge/badge.mdx +8 -8
- package/components/ui/breadcrumb/breadcrumb.mdx +8 -8
- package/components/ui/button/button.mdx +8 -8
- package/components/ui/calendar/calendar.mdx +8 -8
- package/components/ui/card/card.mdx +8 -8
- package/components/ui/carousel/carousel.mdx +8 -8
- package/components/ui/chart/chart.mdx +8 -8
- package/components/ui/chart/chart.test.tsx +178 -178
- package/components/ui/chart/chart.tsx +2245 -2239
- package/components/ui/checkbox/checkbox.mdx +8 -8
- package/components/ui/collapsible/collapsible.mdx +8 -8
- package/components/ui/command/command.mdx +8 -8
- package/components/ui/context-menu/context-menu.mdx +8 -8
- package/components/ui/dialog/dialog.mdx +8 -8
- package/components/ui/drawer/drawer.mdx +8 -8
- package/components/ui/dropdown-menu/dropdown-menu.mdx +8 -8
- package/components/ui/empty/empty.mdx +8 -8
- package/components/ui/file-upload/file-upload.mdx +8 -8
- package/components/ui/hover-card/hover-card.mdx +8 -8
- package/components/ui/input/input.mdx +8 -8
- package/components/ui/input-otp/input-otp.mdx +8 -8
- package/components/ui/label/label.mdx +8 -8
- package/components/ui/map/map.mdx +8 -8
- package/components/ui/menubar/menubar.mdx +8 -8
- package/components/ui/navigation-menu/navigation-menu.mdx +8 -8
- package/components/ui/notification-badge/notification-badge.mdx +8 -8
- package/components/ui/pagination/pagination.mdx +8 -8
- package/components/ui/popover/popover.mdx +8 -8
- package/components/ui/progress/progress.mdx +8 -8
- package/components/ui/radio-group/radio-group.mdx +8 -8
- package/components/ui/rating/rating.mdx +8 -8
- package/components/ui/resizable/resizable.mdx +8 -8
- package/components/ui/route-map/route-map.mdx +8 -8
- package/components/ui/scroll-area/scroll-area.mdx +8 -8
- package/components/ui/search/search.mdx +8 -8
- package/components/ui/select/select.mdx +8 -8
- package/components/ui/separator/separator.mdx +8 -8
- package/components/ui/sheet/sheet.mdx +8 -8
- package/components/ui/simple-map/simple-map.mdx +8 -8
- package/components/ui/skeleton/skeleton.mdx +8 -8
- package/components/ui/slider/slider.mdx +8 -8
- package/components/ui/sonner/sonner.mdx +8 -8
- package/components/ui/stats-card/index.ts +2 -2
- package/components/ui/stats-card/stats-card-skeleton.tsx +60 -60
- package/components/ui/stats-card/stats-card.mdx +8 -8
- package/components/ui/stats-card/stats-card.tsx +109 -109
- package/components/ui/stepper/stepper.mdx +8 -8
- package/components/ui/switch/switch.mdx +8 -8
- package/components/ui/table/table.mdx +8 -8
- package/components/ui/tabs/tabs.mdx +8 -8
- package/components/ui/textarea/textarea.mdx +8 -8
- package/components/ui/timeline/timeline.mdx +8 -8
- package/components/ui/toggle/toggle.mdx +8 -8
- package/components/ui/toggle-group/toggle-group.mdx +8 -8
- package/components/ui/tooltip/tooltip.mdx +8 -8
- package/components/ui/tree-view/tree-view.mdx +8 -8
- package/components.json +511 -511
- package/contexts/AuthContext.tsx +121 -121
- package/contexts/BrandColorsContext.tsx +282 -282
- package/contexts/LanguageContext.test.tsx +121 -121
- package/contexts/LanguageContext.tsx +250 -250
- package/contexts/theme-data.ts +391 -391
- package/dist/{AssistantChart-DoZCyS5r.cjs → AssistantChart-9w31gdAb.cjs} +4 -4
- package/dist/{AssistantChart-CldVCVDe.cjs → AssistantChart-BAudAfne.cjs} +5 -5
- package/dist/{AssistantChart-Bdd44uBn.cjs → AssistantChart-BAx9VQvb.cjs} +127 -388
- package/dist/{AssistantChart-Cu3m7RBo.js → AssistantChart-BP8upjMk.js} +5 -5
- package/dist/{AssistantChart-CFhDdGyU.js → AssistantChart-CVko2A1W.js} +130 -391
- package/dist/{AssistantChart-C_hwFRRr.js → AssistantChart-CVzmmhx4.js} +4 -4
- package/dist/{AudioPlayer-IAU5q5T1.cjs → AudioPlayer-1ypwE2Wh.cjs} +1 -1
- package/dist/{AudioPlayer-CGRUtUdN.js → AudioPlayer-DuKXrCfy.js} +1 -1
- package/dist/{LanguageContext-CS14yCpi.js → LanguageContext-BwhwC3G2.js} +2 -2
- package/dist/{LanguageContext-B_KFTCzT.cjs → LanguageContext-DvUt5jBg.cjs} +2 -2
- package/dist/{ThemeContext-C2EwAPDt.js → ThemeContext-BbBNoFTG.js} +2 -2
- package/dist/{ThemeContext-Bmod0Cg2.cjs → ThemeContext-BblcjQup.cjs} +13 -8
- package/dist/{ThemeContext-BWq9ACPo.js → ThemeContext-Bo-W2WZH.js} +13 -8
- package/dist/{ThemeContext-j5aGtPky.cjs → ThemeContext-CP3a0jxy.cjs} +193 -262
- package/dist/{ThemeContext-vTjumZeM.cjs → ThemeContext-Cmr8Ex8H.cjs} +2 -2
- package/dist/ThemeContext-CpqYShLq.cjs +324 -0
- package/dist/{ThemeContext-CQSo4Iwc.js → ThemeContext-D3LzacmG.js} +8 -1
- package/dist/ThemeContext-Du2nE1PL.js +325 -0
- package/dist/ThemeContext-GeEBTJ3q.cjs +1621 -0
- package/dist/ThemeContext-JyLK9B1o.js +1622 -0
- package/dist/{ThemeContext-CGk3KK0k.cjs → ThemeContext-U4dEYc6C.cjs} +8 -1
- package/dist/{ThemeContext-BXjrgUjW.js → ThemeContext-ept8jhXI.js} +200 -261
- package/dist/{VerifyEmailPage-CGIwmWrm.js → VerifyEmailPage-B31mCrMc.js} +1 -1
- package/dist/{VerifyEmailPage-C0c2e5n0.js → VerifyEmailPage-BE-L9mB7.js} +7 -7
- package/dist/{VerifyEmailPage-DSBMRHtl.js → VerifyEmailPage-BIBOKV7Z.js} +41 -36
- package/dist/{VerifyEmailPage-DgIid028.js → VerifyEmailPage-BJjAMUTW.js} +4 -4
- package/dist/{VerifyEmailPage--1Vurewl.cjs → VerifyEmailPage-BRSP-Pwt.cjs} +3 -3
- package/dist/{VerifyEmailPage-Cwi3kbol.cjs → VerifyEmailPage-Bae2cBXT.cjs} +7 -7
- package/dist/{VerifyEmailPage-De6bQjrz.cjs → VerifyEmailPage-BiRm7Nh4.cjs} +41 -36
- package/dist/{VerifyEmailPage-ByerOcm4.cjs → VerifyEmailPage-Bv8Ah_TK.cjs} +23 -20
- package/dist/VerifyEmailPage-Bvfv8HVQ.js +3214 -0
- package/dist/{VerifyEmailPage-BComraR7.cjs → VerifyEmailPage-CR7kb5df.cjs} +22 -12
- package/dist/{VerifyEmailPage-CpqqpLpo.cjs → VerifyEmailPage-C_Zk6Gen.cjs} +1 -1
- package/dist/{VerifyEmailPage-MTD7AG1Z.js → VerifyEmailPage-C_ihbcth.js} +4 -4
- package/dist/{VerifyEmailPage-1WwWczAn.js → VerifyEmailPage-CbgjOF0v.js} +22 -12
- package/dist/{VerifyEmailPage-DvMLZgFt.js → VerifyEmailPage-CdYPSJoO.js} +1 -1
- package/dist/{VerifyEmailPage-By3Jf__L.cjs → VerifyEmailPage-CkBYfsNy.cjs} +4 -4
- package/dist/{VerifyEmailPage-CJLz3jrn.js → VerifyEmailPage-Cyl55sJb.js} +23 -20
- package/dist/VerifyEmailPage-D-FRj5TU.cjs +3213 -0
- package/dist/{VerifyEmailPage-B4peJjAT.cjs → VerifyEmailPage-DF2ilhum.cjs} +334 -356
- package/dist/{VerifyEmailPage-CYXtbKi3.cjs → VerifyEmailPage-DMBh4NM9.cjs} +1 -1
- package/dist/{VerifyEmailPage-CgMxRb4z.js → VerifyEmailPage-DTtFfC-J.js} +3 -3
- package/dist/{VerifyEmailPage-CFLMls1p.cjs → VerifyEmailPage-Dt7zgA4w.cjs} +4 -4
- package/dist/{VerifyEmailPage-C5TNQTBa.js → VerifyEmailPage-EhudUdqF.js} +343 -355
- package/dist/{VerifyEmailPage-DGhuIqkb.js → VerifyEmailPage-X14vhdyl.js} +4 -4
- package/dist/VerifyEmailPage-hdB8JQGv.cjs +3213 -0
- package/dist/{VerifyEmailPage-Bp1XXl3H.cjs → VerifyEmailPage-u_Dn7t1U.cjs} +4 -4
- package/dist/VerifyEmailPage-vYHbYK3q.js +3214 -0
- package/dist/{XerticaProvider-CBGc4EMA.cjs → XerticaProvider-AChwphCO.cjs} +4 -4
- package/dist/{XerticaProvider-BIrqfZ-i.cjs → XerticaProvider-AbWlr7Af.cjs} +8 -11
- package/dist/{XerticaProvider-D-yNhF94.cjs → XerticaProvider-B8CaV7xu.cjs} +1 -1
- package/dist/{XerticaProvider-CEoWMTxu.js → XerticaProvider-BITjgC5p.js} +2 -2
- package/dist/{XerticaProvider-CllrbMEJ.cjs → XerticaProvider-By8q3Roe.cjs} +2 -2
- package/dist/{XerticaProvider-C1DKnvLh.js → XerticaProvider-CUYJZc32.js} +4 -4
- package/dist/{XerticaProvider-ET0ihewn.cjs → XerticaProvider-CW9hpCdF.cjs} +2 -2
- package/dist/{XerticaProvider-Dt5HEzbQ.js → XerticaProvider-CWgby5mY.js} +10 -10
- package/dist/XerticaProvider-CWs6EwNa.js +49 -0
- package/dist/XerticaProvider-CjQAQPcn.cjs +48 -0
- package/dist/XerticaProvider-D5lLumH-.js +49 -0
- package/dist/{XerticaProvider-DYq4JWtg.js → XerticaProvider-DQtvJU7m.js} +1 -1
- package/dist/XerticaProvider-qQUDop71.cjs +48 -0
- package/dist/{XerticaProvider-B7EVH-NF.js → XerticaProvider-siSt9uG2.js} +2 -2
- package/dist/{XerticaXLogo-Zw2B276b.cjs → XerticaXLogo-8TTzBjHw.cjs} +1 -1
- package/dist/{XerticaXLogo-B7xQ5dhi.js → XerticaXLogo-BWaag64t.js} +1 -1
- package/dist/{XerticaXLogo-DZbo4vOE.js → XerticaXLogo-CFuIlYFH.js} +12 -12
- package/dist/{XerticaXLogo-bvZSgwGF.cjs → XerticaXLogo-CU-U-GP4.cjs} +7 -13
- package/dist/XerticaXLogo-ChryA6xj.js +252 -0
- package/dist/{XerticaXLogo-CQUUjXoH.cjs → XerticaXLogo-CziKMQil.cjs} +8 -8
- package/dist/XerticaXLogo-DHz5SugF.js +252 -0
- package/dist/XerticaXLogo-DTee_y8X.cjs +251 -0
- package/dist/{XerticaXLogo-Cmsp-Eey.js → XerticaXLogo-DfUvz-lD.js} +9 -9
- package/dist/XerticaXLogo-kslQ8Tk_.cjs +251 -0
- package/dist/{alert-dialog-s-vmNkJ_.js → alert-dialog-iDe5VE5o.js} +3 -3
- package/dist/{alert-dialog-DSKByiKZ.cjs → alert-dialog-yckpaOpy.cjs} +3 -3
- package/dist/cli.js +16 -6
- package/dist/components/ui/chart/chart.d.ts +7 -5
- package/dist/{google-maps-loader-Y-QkD-Li.cjs → google-maps-loader-BqsYL48U.cjs} +0 -5
- package/dist/{google-maps-loader-CTYySAun.js → google-maps-loader-t2IlYBzw.js} +0 -4
- package/dist/index-CkTUgOwX.js +8 -0
- package/dist/{index-COtD8bRW.cjs → index-D3RLKRAs.cjs} +1 -1
- package/dist/index.cjs.js +2 -2
- package/dist/index.es.js +2 -2
- package/dist/index.umd.js +454 -1027
- package/dist/layout.cjs.js +1 -1
- package/dist/layout.es.js +1 -1
- package/dist/pages.cjs.js +1 -1
- package/dist/pages.es.js +1 -1
- package/dist/{sidebar-DAaY8bRU.cjs → sidebar-B3EYhli0.cjs} +33 -24
- package/dist/{sidebar-nzPoVHBQ.cjs → sidebar-B9NR0lCe.cjs} +46 -41
- package/dist/{sidebar-CeTMuzOx.cjs → sidebar-BvF5I2Ue.cjs} +47 -128
- package/dist/{sidebar-q7P2Godd.cjs → sidebar-C5B_LHek.cjs} +1 -1
- package/dist/{sidebar-CrQDDdcz.js → sidebar-CA6_ek3f.js} +33 -24
- package/dist/sidebar-CLmIjgNd.cjs +1136 -0
- package/dist/{sidebar-BxGXsDAd.cjs → sidebar-CVUGHOS_.cjs} +8 -16
- package/dist/{sidebar-BViy8Eeu.js → sidebar-CmvwjnVb.js} +9 -17
- package/dist/{sidebar-B6SlKZYN.js → sidebar-CplprZpM.js} +49 -40
- package/dist/sidebar-Duermn32.js +1133 -0
- package/dist/{sidebar-BbVIQvlP.js → sidebar-Dz7bd3zP.js} +1 -1
- package/dist/{sidebar-0ocFLSks.js → sidebar-KIS0C2JH.js} +50 -127
- package/dist/sidebar-OTO_up7Z.js +801 -0
- package/dist/sidebar-zowjejT2.cjs +800 -0
- package/dist/{use-audio-player-nv8ZSGa1.js → use-audio-player-Bkh23vQ3.js} +3 -7
- package/dist/{use-audio-player-NKsWyjWu.cjs → use-audio-player-Dn1NR9xN.cjs} +3 -7
- package/dist/{xertica-assistant-dyP7KHM5.cjs → xertica-assistant-B1IaHXnB.cjs} +388 -529
- package/dist/{xertica-assistant-ciJaWqm1.js → xertica-assistant-BMqdyRVi.js} +10 -28
- package/dist/{xertica-assistant-V_IdW4WF.cjs → xertica-assistant-Bj3vBCq_.cjs} +9 -27
- package/dist/{xertica-assistant-yX1CFBBo.js → xertica-assistant-DPsESB6t.js} +390 -531
- package/dist/{CodeBlock-7TTgmdGG.cjs → xertica-assistant-Qp3ydksa.cjs} +51 -263
- package/dist/{CodeBlock-BeSt1h5P.js → xertica-assistant-gnCJdcZY.js} +7 -219
- package/dist/xertica-ui.css +2 -2
- package/docs/architecture-improvements.md +456 -456
- package/docs/architecture.md +312 -312
- package/docs/components/assistant.md +428 -428
- package/docs/components/branding.md +252 -252
- package/docs/components/card-patterns.md +447 -447
- package/docs/components/error-boundary.md +201 -201
- package/docs/components/hooks.md +432 -432
- package/docs/components/language-selector.md +176 -176
- package/docs/components/pages.md +323 -323
- package/docs/components/sidebar.md +331 -331
- package/docs/components/stats-card.md +138 -138
- package/docs/doc-audit.md +244 -244
- package/docs/getting-started.md +616 -616
- package/docs/guidelines.md +330 -330
- package/docs/i18n.md +480 -480
- package/docs/installation.md +268 -268
- package/docs/llms.md +295 -295
- package/docs/state-management.md +289 -289
- package/guidelines/Guidelines.md +409 -409
- package/llms-compact.txt +1 -1
- package/llms-full.txt +10688 -10688
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/styles/xertica/base.css +90 -90
- package/styles/xertica/tokens.css +240 -240
- package/templates/.prettierignore +4 -4
- package/templates/.prettierrc +10 -10
- package/templates/CLAUDE.md +180 -180
- package/templates/package.json +2 -2
- package/templates/src/app/App.tsx +46 -46
- package/templates/src/app/components/AuthGuard.tsx +131 -131
- package/templates/src/features/assistant/data/mock.ts +75 -75
- package/templates/src/features/assistant/hooks/useAssistantConfig.ts +20 -20
- package/templates/src/features/assistant/index.ts +5 -5
- package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -70
- package/templates/src/features/auth/ui/LoginContent.tsx +92 -92
- package/templates/src/features/auth/ui/ResetPasswordContent.tsx +183 -183
- package/templates/src/features/auth/ui/SocialLoginButtons.tsx +78 -78
- package/templates/src/features/auth/ui/VerifyEmailContent.tsx +80 -80
- package/templates/src/features/home/data/mock.ts +41 -41
- package/templates/src/features/home/hooks/useFeatureCards.ts +20 -20
- package/templates/src/features/home/index.ts +11 -11
- package/templates/src/features/home/ui/HomeContent.tsx +117 -117
- package/templates/src/features/template/ui/CrudTemplate.tsx +112 -112
- package/templates/src/features/template/ui/DashboardTemplate.tsx +110 -110
- package/templates/src/features/template/ui/FormTemplate.tsx +117 -117
- package/templates/src/features/template/ui/LoginTemplate.tsx +59 -59
- package/templates/src/features/template/ui/TemplateContent.tsx +1322 -1322
- package/templates/src/i18n.ts +124 -124
- package/templates/src/locales/en/common.json +21 -21
- package/templates/src/locales/en/components/activityCard.json +10 -10
- package/templates/src/locales/en/components/assistant.json +119 -119
- package/templates/src/locales/en/components/media.json +29 -29
- package/templates/src/locales/en/components/notificationCard.json +5 -5
- package/templates/src/locales/en/components/profileCard.json +8 -8
- package/templates/src/locales/en/components/projectCard.json +10 -10
- package/templates/src/locales/en/components/sidebar.json +14 -14
- package/templates/src/locales/en/components/stats.json +8 -8
- package/templates/src/locales/en/components/team.json +14 -14
- package/templates/src/locales/en/errors.json +9 -9
- package/templates/src/locales/en/languageSelector.json +7 -7
- package/templates/src/locales/en/nav.json +6 -6
- package/templates/src/locales/en/pages/crudTemplate.json +25 -25
- package/templates/src/locales/en/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/en/pages/forgotPassword.json +10 -10
- package/templates/src/locales/en/pages/formTemplate.json +16 -16
- package/templates/src/locales/en/pages/home.json +7 -7
- package/templates/src/locales/en/pages/login.json +15 -15
- package/templates/src/locales/en/pages/loginTemplate.json +9 -9
- package/templates/src/locales/en/pages/resetPassword.json +18 -18
- package/templates/src/locales/en/pages/templates.json +317 -317
- package/templates/src/locales/en/pages/verifyEmail.json +12 -12
- package/templates/src/locales/en/themeToggle.json +6 -6
- package/templates/src/locales/es/common.json +21 -21
- package/templates/src/locales/es/components/activityCard.json +10 -10
- package/templates/src/locales/es/components/assistant.json +119 -119
- package/templates/src/locales/es/components/media.json +29 -29
- package/templates/src/locales/es/components/notificationCard.json +5 -5
- package/templates/src/locales/es/components/profileCard.json +8 -8
- package/templates/src/locales/es/components/projectCard.json +10 -10
- package/templates/src/locales/es/components/sidebar.json +14 -14
- package/templates/src/locales/es/components/stats.json +8 -8
- package/templates/src/locales/es/components/team.json +14 -14
- package/templates/src/locales/es/errors.json +9 -9
- package/templates/src/locales/es/languageSelector.json +7 -7
- package/templates/src/locales/es/nav.json +6 -6
- package/templates/src/locales/es/pages/crudTemplate.json +25 -25
- package/templates/src/locales/es/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/es/pages/forgotPassword.json +10 -10
- package/templates/src/locales/es/pages/formTemplate.json +16 -16
- package/templates/src/locales/es/pages/home.json +7 -7
- package/templates/src/locales/es/pages/login.json +15 -15
- package/templates/src/locales/es/pages/loginTemplate.json +9 -9
- package/templates/src/locales/es/pages/resetPassword.json +18 -18
- package/templates/src/locales/es/pages/templates.json +317 -317
- package/templates/src/locales/es/pages/verifyEmail.json +12 -12
- package/templates/src/locales/es/themeToggle.json +6 -6
- package/templates/src/locales/pt-BR/common.json +21 -21
- package/templates/src/locales/pt-BR/components/activityCard.json +10 -10
- package/templates/src/locales/pt-BR/components/assistant.json +119 -119
- package/templates/src/locales/pt-BR/components/media.json +29 -29
- package/templates/src/locales/pt-BR/components/notificationCard.json +5 -5
- package/templates/src/locales/pt-BR/components/profileCard.json +8 -8
- package/templates/src/locales/pt-BR/components/projectCard.json +10 -10
- package/templates/src/locales/pt-BR/components/sidebar.json +14 -14
- package/templates/src/locales/pt-BR/components/stats.json +8 -8
- package/templates/src/locales/pt-BR/components/team.json +14 -14
- package/templates/src/locales/pt-BR/errors.json +9 -9
- package/templates/src/locales/pt-BR/languageSelector.json +7 -7
- package/templates/src/locales/pt-BR/nav.json +6 -6
- package/templates/src/locales/pt-BR/pages/crudTemplate.json +25 -25
- package/templates/src/locales/pt-BR/pages/dashboardTemplate.json +20 -20
- package/templates/src/locales/pt-BR/pages/forgotPassword.json +10 -10
- package/templates/src/locales/pt-BR/pages/formTemplate.json +16 -16
- package/templates/src/locales/pt-BR/pages/home.json +7 -7
- package/templates/src/locales/pt-BR/pages/login.json +15 -15
- package/templates/src/locales/pt-BR/pages/loginTemplate.json +9 -9
- package/templates/src/locales/pt-BR/pages/resetPassword.json +18 -18
- package/templates/src/locales/pt-BR/pages/templates.json +317 -317
- package/templates/src/locales/pt-BR/pages/verifyEmail.json +12 -12
- package/templates/src/locales/pt-BR/themeToggle.json +6 -6
- package/templates/src/pages/AssistantPage.tsx +470 -470
- package/templates/src/pages/HomePage.tsx +53 -53
- package/templates/src/shared/error-boundary.tsx +150 -150
- package/templates/src/shared/error-fallbacks.tsx +222 -222
- package/templates/src/styles/xertica/tokens.css +240 -240
- package/templates/vite.config.js +20 -20
- package/templates/vite.config.ts +55 -55
- package/dist/AssistantChart-BKVtGUKF.js +0 -3383
- package/dist/AssistantChart-CxGjH7Qk.js +0 -3477
- package/dist/AssistantChart-DIpshm3i.js +0 -4784
- package/dist/AssistantChart-D_PTeu8P.cjs +0 -3503
- package/dist/AssistantChart-WeycT5Pd.cjs +0 -3551
- package/dist/AssistantChart-zjsy2GaZ.cjs +0 -4810
- package/dist/AudioPlayer-B1lt5cPl.cjs +0 -989
- package/dist/AudioPlayer-BZ7bibzU.cjs +0 -982
- package/dist/AudioPlayer-BpRPS4-1.cjs +0 -1277
- package/dist/AudioPlayer-C12BjQBV.cjs +0 -997
- package/dist/AudioPlayer-CFeV8t-5.cjs +0 -936
- package/dist/AudioPlayer-Coly3q5R.js +0 -1278
- package/dist/AudioPlayer-CySJIyvL.js +0 -937
- package/dist/AudioPlayer-DMcG_c7L.js +0 -990
- package/dist/AudioPlayer-DcFKRJE_.js +0 -998
- package/dist/AudioPlayer-e8LfNoqO.js +0 -983
- package/dist/BrandColorsContext-565dDHd5.js +0 -660
- package/dist/BrandColorsContext-BcJbtkqn.cjs +0 -659
- package/dist/CodeBlock-BgfYL_rD.cjs +0 -2094
- package/dist/CodeBlock-BlcqlA9M.cjs +0 -2094
- package/dist/CodeBlock-Bnmeu5ez.cjs +0 -2094
- package/dist/CodeBlock-BtfPlbAI.js +0 -2078
- package/dist/CodeBlock-CIySIuYr.js +0 -2078
- package/dist/CodeBlock-CuPtUM-7.cjs +0 -2094
- package/dist/CodeBlock-D6ffWXgc.js +0 -2078
- package/dist/CodeBlock-D8dcwbit.cjs +0 -2094
- package/dist/CodeBlock-DMZrFnlw.cjs +0 -2094
- package/dist/CodeBlock-DlBehYN8.js +0 -2078
- package/dist/CodeBlock-DnYNI8rQ.js +0 -2078
- package/dist/CodeBlock-DvKWbSnE.cjs +0 -2094
- package/dist/CodeBlock-DwMCfkFY.js +0 -2078
- package/dist/CodeBlock-Dy6CNYyj.js +0 -2078
- package/dist/CodeBlock-U1pPOQI7.cjs +0 -2094
- package/dist/CodeBlock-f_GpNhEB.js +0 -2078
- package/dist/CodeBlock-oB6u8nI1.js +0 -2078
- package/dist/CodeBlock-tZC31B73.cjs +0 -2094
- package/dist/FeatureCard-CxC-7C-C.cjs +0 -300
- package/dist/FeatureCard-DbHWCb4E.js +0 -301
- package/dist/ImageWithFallback-CGtidP6B.cjs +0 -4542
- package/dist/ImageWithFallback-lsg3pdFg.js +0 -4508
- package/dist/LanguageSelector-B5YfbHra.js +0 -231
- package/dist/LanguageSelector-D6uacAIM.cjs +0 -230
- package/dist/LayoutContext-B45-e9DI.cjs +0 -93
- package/dist/LayoutContext-BAql6ZRY.js +0 -97
- package/dist/LayoutContext-Bav3UMEA.js +0 -94
- package/dist/LayoutContext-BvK-ggDa.cjs +0 -96
- package/dist/ThemeContext-BoH4NLfN.js +0 -734
- package/dist/ThemeContext-r69W20Xg.cjs +0 -733
- package/dist/VerifyEmailPage-COiyNl1y.js +0 -2825
- package/dist/VerifyEmailPage-CqKsR2v8.js +0 -2827
- package/dist/VerifyEmailPage-DjQKRlUS.cjs +0 -2824
- package/dist/VerifyEmailPage-s-1X3LDJ.cjs +0 -2826
- package/dist/XerticaOrbe-KL1RBHzw.cjs +0 -1354
- package/dist/XerticaOrbe-zwS1p2a8.js +0 -1355
- package/dist/XerticaProvider-6btlAlzc.js +0 -17
- package/dist/XerticaProvider-BNoNOxQ5.cjs +0 -16
- package/dist/XerticaProvider-BlY2limY.cjs +0 -38
- package/dist/XerticaProvider-DDuiIcKo.js +0 -39
- package/dist/XerticaProvider-cI9hSs27.cjs +0 -38
- package/dist/XerticaProvider-hSwhNQex.js +0 -39
- package/dist/alert-dialog-BOje--vD.js +0 -847
- package/dist/alert-dialog-BtEuQqrg.cjs +0 -870
- package/dist/breadcrumb-CqJ7bHY5.js +0 -161
- package/dist/breadcrumb-m9Hb2_XN.cjs +0 -177
- package/dist/components/assistant/xertica-assistant/hooks/index.d.ts +0 -6
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-conversations.d.ts +0 -21
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-messages.d.ts +0 -49
- package/dist/components/assistant/xertica-assistant/hooks/use-assistant-suggestions.d.ts +0 -16
- package/dist/components/blocks/audio-player/AudioPlayer.d.ts +0 -35
- package/dist/components/blocks/audio-player/index.d.ts +0 -1
- package/dist/components/blocks/document-editor/DocumentEditor.d.ts +0 -26
- package/dist/components/blocks/document-editor/index.d.ts +0 -1
- package/dist/components/blocks/podcast-player/PodcastPlayer.d.ts +0 -41
- package/dist/components/blocks/podcast-player/index.d.ts +0 -1
- package/dist/components/ui/chart/parts/chart-dashboard.d.ts +0 -113
- package/dist/components/ui/chart/parts/chart-metric.d.ts +0 -118
- package/dist/components/ui/chart/parts/chart-primitives.d.ts +0 -101
- package/dist/components/ui/chart/parts/chart-shared.d.ts +0 -20
- package/dist/components/ui/chart/parts/chart-utils.d.ts +0 -12
- package/dist/components/ui/chart/parts/index.d.ts +0 -5
- package/dist/dropdown-menu-BDB5CmQs.cjs +0 -247
- package/dist/dropdown-menu-DQidbKBD.js +0 -231
- package/dist/google-maps-loader-BFWp6VPd.js +0 -287
- package/dist/google-maps-loader-BKcdgFbu.cjs +0 -312
- package/dist/google-maps-loader-CumCNXeG.js +0 -312
- package/dist/google-maps-loader-eS3uQ5TA.cjs +0 -287
- package/dist/header-Cgy6vYPk.cjs +0 -731
- package/dist/header-DRlT4jgI.js +0 -715
- package/dist/header-Dux00SI4.cjs +0 -731
- package/dist/header-EkGKXPsD.js +0 -715
- package/dist/header-WfEywpyc.cjs +0 -731
- package/dist/header-tifNQn2U.js +0 -715
- package/dist/index-BhapVLVj.js +0 -8
- package/dist/index-D6fxYEY8.cjs +0 -7
- package/dist/index-DAIp0_HK.js +0 -8
- package/dist/index-DW5tYe26.js +0 -8
- package/dist/index-GA__GvnG.cjs +0 -7
- package/dist/input-2R4loU86.js +0 -127
- package/dist/input-DWANSKGb.cjs +0 -145
- package/dist/progress-DPtzoVV8.js +0 -175
- package/dist/progress-EeaoqqUs.cjs +0 -191
- package/dist/rich-text-editor-0mraWT5y.cjs +0 -2376
- package/dist/rich-text-editor-B-IkcPD0.js +0 -2874
- package/dist/rich-text-editor-B6jMRLzk.cjs +0 -1939
- package/dist/rich-text-editor-B8_oYcIR.js +0 -1730
- package/dist/rich-text-editor-B9UbSXNb.js +0 -1203
- package/dist/rich-text-editor-BYuRBNBU.js +0 -2373
- package/dist/rich-text-editor-Bb9pySTs.cjs +0 -2374
- package/dist/rich-text-editor-BcL6L3cm.cjs +0 -2374
- package/dist/rich-text-editor-BoVZYtTs.cjs +0 -2391
- package/dist/rich-text-editor-Bp3zQqMC.js +0 -2954
- package/dist/rich-text-editor-CMgSN_w2.js +0 -1189
- package/dist/rich-text-editor-CPV1lEPH.cjs +0 -1748
- package/dist/rich-text-editor-CeucBdIv.cjs +0 -2971
- package/dist/rich-text-editor-CoKqbCtu.cjs +0 -1799
- package/dist/rich-text-editor-Cw56T_mB.js +0 -2356
- package/dist/rich-text-editor-Cyt8qs2b.js +0 -1921
- package/dist/rich-text-editor-D6H84OcX.cjs +0 -1220
- package/dist/rich-text-editor-D76gD-QI.js +0 -2328
- package/dist/rich-text-editor-DKkokOnA.js +0 -1781
- package/dist/rich-text-editor-DNsdpN64.cjs +0 -2359
- package/dist/rich-text-editor-DfG8bCyY.js +0 -2358
- package/dist/rich-text-editor-Dxjw31Z4.js +0 -2341
- package/dist/rich-text-editor-DzP0Epmb.js +0 -2356
- package/dist/rich-text-editor-bRkNoeZY.cjs +0 -2891
- package/dist/rich-text-editor-lyYE2ZG5.cjs +0 -1207
- package/dist/rich-text-editor-skplNlBM.cjs +0 -2345
- package/dist/select-Bkbr0f-Z.cjs +0 -162
- package/dist/select-CvIVdX2n.js +0 -145
- package/dist/sidebar-CK_0ZQHj.cjs +0 -803
- package/dist/sidebar-CUuOvYhK.js +0 -787
- package/dist/sidebar-DQj1z3jG.cjs +0 -758
- package/dist/sidebar-Djn5syhi.cjs +0 -786
- package/dist/sidebar-LluMXfam.js +0 -759
- package/dist/sidebar-_rT7rBMk.js +0 -787
- package/dist/slider-Bc5Hd0y1.js +0 -56
- package/dist/slider-N7hFFj6X.cjs +0 -73
- package/dist/tooltip-Ded96neP.cjs +0 -137
- package/dist/tooltip-HDOoD2-0.js +0 -120
- package/dist/use-audio-player-B31J-aqh.cjs +0 -187
- package/dist/use-audio-player-BkmEmj8Q.js +0 -185
- package/dist/use-audio-player-CLFTWFW1.cjs +0 -184
- package/dist/use-audio-player-CLLn00I6.js +0 -188
- package/dist/use-file-upload-BcjEo2S5.js +0 -404
- package/dist/use-file-upload-CRJR68Tj.cjs +0 -403
- package/dist/use-mobile-B0hNy_Y6.cjs +0 -4303
- package/dist/use-mobile-BXuYROXM.js +0 -4202
- package/dist/use-mobile-Bbd51ASU.cjs +0 -4392
- package/dist/use-mobile-Bk6CX-TC.js +0 -4359
- package/dist/use-mobile-BvYdisLP.js +0 -4202
- package/dist/use-mobile-BzuxjzNX.cjs +0 -4392
- package/dist/use-mobile-CG2-SdXV.cjs +0 -4235
- package/dist/use-mobile-CKb5pqTs.js +0 -4269
- package/dist/use-mobile-CYuAuGDl.js +0 -4202
- package/dist/use-mobile-CaENcqm-.js +0 -4508
- package/dist/use-mobile-CbrYgJGJ.js +0 -4203
- package/dist/use-mobile-Cd4xPrKq.cjs +0 -46
- package/dist/use-mobile-DMOvImGQ.cjs +0 -4542
- package/dist/use-mobile-DRB3BQgD.cjs +0 -4235
- package/dist/use-mobile-DZvv7QMR.js +0 -4359
- package/dist/use-mobile-DdI_TXam.cjs +0 -4235
- package/dist/use-mobile-DlceKf8a.js +0 -4359
- package/dist/use-mobile-DsOnow1o.cjs +0 -4236
- package/dist/use-mobile-Kcj6jSnK.cjs +0 -4392
- package/dist/use-mobile-bnKcua_i.js +0 -4202
- package/dist/use-mobile-j4w2Jrf1.js +0 -30
- package/dist/use-mobile-ncXBeE2z.cjs +0 -4235
- package/dist/use-rich-text-editor-DjiddBGv.js +0 -282
- package/dist/use-rich-text-editor-lpeswbCs.cjs +0 -281
- package/dist/xertica-assistant-BdiZag0h.js +0 -2187
- package/dist/xertica-assistant-CrgTb6Hs.cjs +0 -2155
- package/dist/xertica-assistant-DCsnQyi5.js +0 -2156
- package/dist/xertica-assistant-DUBpmEgo.cjs +0 -2186
- package/dist/{rich-text-editor-DgF8s7xW.js → rich-text-editor-BmsjY03B.js} +26 -26
- package/dist/{rich-text-editor-mWoaSCE4.cjs → rich-text-editor-GS2kpTAK.cjs} +26 -26
|
@@ -1,611 +1,611 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { useAssistant } from './use-assistant';
|
|
3
|
-
import { motion, AnimatePresence } from 'framer-motion';
|
|
4
|
-
import { useTranslation } from 'react-i18next';
|
|
5
|
-
import { ScrollArea } from '../../ui/scroll-area';
|
|
6
|
-
import { ModernChatInput } from '../modern-chat-input';
|
|
7
|
-
import { XerticaOrbe } from '../../brand/xertica-orbe';
|
|
8
|
-
import { Button } from '../../ui/button';
|
|
9
|
-
import { cn } from '../../shared/utils';
|
|
10
|
-
|
|
11
|
-
// Sub-components
|
|
12
|
-
import {
|
|
13
|
-
AssistantCollapsedView,
|
|
14
|
-
AssistantHeader,
|
|
15
|
-
AssistantTabBar,
|
|
16
|
-
AssistantWelcomeScreen,
|
|
17
|
-
AssistantMessageBubble,
|
|
18
|
-
AssistantTypingIndicator,
|
|
19
|
-
AssistantConversationList,
|
|
20
|
-
AssistantFeedbackDialog,
|
|
21
|
-
AssistantDocumentEditor,
|
|
22
|
-
} from './parts';
|
|
23
|
-
import type { EvaluationState } from './parts';
|
|
24
|
-
|
|
25
|
-
// ============================================================================
|
|
26
|
-
// TypeScript Interfaces & Types — imported from shared types.ts and re-exported
|
|
27
|
-
// for backward compatibility with consumers that import from xertica-assistant.
|
|
28
|
-
// ============================================================================
|
|
29
|
-
import type {
|
|
30
|
-
MessageType,
|
|
31
|
-
AttachmentType,
|
|
32
|
-
SearchResultType,
|
|
33
|
-
AssistantMode,
|
|
34
|
-
AssistantTab,
|
|
35
|
-
SearchResult,
|
|
36
|
-
SearchSource,
|
|
37
|
-
SearchCommand,
|
|
38
|
-
Message,
|
|
39
|
-
Conversation,
|
|
40
|
-
Suggestion,
|
|
41
|
-
MockResponse,
|
|
42
|
-
} from './types';
|
|
43
|
-
|
|
44
|
-
export type {
|
|
45
|
-
MessageType,
|
|
46
|
-
AttachmentType,
|
|
47
|
-
SearchResultType,
|
|
48
|
-
AssistantMode,
|
|
49
|
-
AssistantTab,
|
|
50
|
-
SearchResult,
|
|
51
|
-
SearchSource,
|
|
52
|
-
SearchCommand,
|
|
53
|
-
Message,
|
|
54
|
-
Conversation,
|
|
55
|
-
Suggestion,
|
|
56
|
-
MockResponse,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// ============================================================================
|
|
60
|
-
// Component Props
|
|
61
|
-
// ============================================================================
|
|
62
|
-
|
|
63
|
-
export interface XerticaAssistantProps {
|
|
64
|
-
/**
|
|
65
|
-
* Layout mode for the assistant panel
|
|
66
|
-
* @default 'expanded'
|
|
67
|
-
*/
|
|
68
|
-
mode?: AssistantMode;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Whether the panel is expanded (only applies when `mode='expanded'`)
|
|
72
|
-
* @default true
|
|
73
|
-
*/
|
|
74
|
-
isExpanded?: boolean;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Callback fired when the assistant panel is expanded or collapsed
|
|
78
|
-
*/
|
|
79
|
-
onToggle?: () => void;
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Initially selected tab
|
|
83
|
-
* @default 'chat'
|
|
84
|
-
*/
|
|
85
|
-
defaultTab?: AssistantTab;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Enables demo mode — generates mock AI responses without a real API key
|
|
89
|
-
*/
|
|
90
|
-
demoMode?: boolean;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Custom mock responses to use in demo mode
|
|
94
|
-
*/
|
|
95
|
-
customResponses?: MockResponse[];
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Callback fired when the user navigates to the settings page
|
|
99
|
-
*/
|
|
100
|
-
onNavigateSettings?: () => void;
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Callback fired when the user navigates to the full-page assistant view
|
|
104
|
-
*/
|
|
105
|
-
onNavigateFullPage?: () => void;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Display name of the logged-in user
|
|
109
|
-
* @default 'User'
|
|
110
|
-
*/
|
|
111
|
-
userName?: string;
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Pre-loaded messages to hydrate an existing conversation
|
|
115
|
-
*/
|
|
116
|
-
initialMessages?: Message[];
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Previously saved conversations shown in the history panel
|
|
120
|
-
*/
|
|
121
|
-
savedConversations?: Conversation[];
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Suggested prompts shown to the user in the empty state
|
|
125
|
-
*/
|
|
126
|
-
suggestions?: Suggestion[];
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Subtitle shown below the user's name in the empty state.
|
|
130
|
-
* @default 'Como posso ajudar?'
|
|
131
|
-
*/
|
|
132
|
-
welcomeMessage?: string;
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Callback fired when the user sends a message
|
|
136
|
-
*/
|
|
137
|
-
onSendMessage?: (message: string) => void;
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Callback fired when the user attaches a file
|
|
141
|
-
*/
|
|
142
|
-
onFileAttach?: (file: File) => void;
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* If true, shows a typing indicator while waiting for an AI response
|
|
146
|
-
*/
|
|
147
|
-
isProcessing?: boolean;
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Custom panel width (only applies when `mode='expanded'`)
|
|
151
|
-
*/
|
|
152
|
-
width?: string;
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Custom panel height (only applies when `mode='fullPage'`)
|
|
156
|
-
*/
|
|
157
|
-
height?: string;
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Additional CSS classes for the root container
|
|
161
|
-
*/
|
|
162
|
-
className?: string;
|
|
163
|
-
mobileFloating?: boolean;
|
|
164
|
-
/**
|
|
165
|
-
* Custom response generator function — overrides demo mode defaults
|
|
166
|
-
* @param message The user's input message
|
|
167
|
-
* @returns A promise or direct value resolving to either a markdown string or a partial `Message` object
|
|
168
|
-
*/
|
|
169
|
-
responseGenerator?: (
|
|
170
|
-
message: string
|
|
171
|
-
) => Promise<string | Partial<Message>> | string | Partial<Message>;
|
|
172
|
-
/**
|
|
173
|
-
* Extended suggestions shown when the user clicks "More suggestions"
|
|
174
|
-
*/
|
|
175
|
-
richSuggestions?: Suggestion[];
|
|
176
|
-
/**
|
|
177
|
-
* Callback fired when the user clicks a rich suggestion item
|
|
178
|
-
*/
|
|
179
|
-
onRichAction?: (actionId: string, actionText: string) => void;
|
|
180
|
-
/**
|
|
181
|
-
* Callback fired when the user rates a message (thumbs up/down)
|
|
182
|
-
*/
|
|
183
|
-
onEvaluation?: (messageId: string, type: 'like' | 'dislike', reason?: string) => void;
|
|
184
|
-
/**
|
|
185
|
-
* Negative feedback categories shown in the dislike dropdown
|
|
186
|
-
*/
|
|
187
|
-
feedbackOptions?: string[];
|
|
188
|
-
|
|
189
|
-
// ============================================================================
|
|
190
|
-
// Feature Flags — Controls individual assistant capabilities
|
|
191
|
-
// ============================================================================
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Whether to show the conversation history tab and collapsed icon.
|
|
195
|
-
* @default true
|
|
196
|
-
*/
|
|
197
|
-
showHistory?: boolean;
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Whether to show the favorites tab and collapsed icon.
|
|
201
|
-
* @default true
|
|
202
|
-
*/
|
|
203
|
-
showFavorites?: boolean;
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Whether to enable audio input (voice recording / audio upload) in the chat.
|
|
207
|
-
* @default true
|
|
208
|
-
*/
|
|
209
|
-
enableAudioInput?: boolean;
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Whether to enable file attachment in the chat input.
|
|
213
|
-
* @default true
|
|
214
|
-
*/
|
|
215
|
-
enableFileAttachment?: boolean;
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Whether to enable the "Create document" action in the chat input.
|
|
219
|
-
* @default true
|
|
220
|
-
*/
|
|
221
|
-
enableDocumentCreation?: boolean;
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Whether to enable podcast generation (action chip + per-message button).
|
|
225
|
-
* @default true
|
|
226
|
-
*/
|
|
227
|
-
enablePodcastGeneration?: boolean;
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Whether to enable the "Search" action in the chat input.
|
|
231
|
-
* @default true
|
|
232
|
-
*/
|
|
233
|
-
enableSearch?: boolean;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// ============================================================================
|
|
237
|
-
// Main Component
|
|
238
|
-
// ============================================================================
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* XerticaAssistant - Full-featured AI assistant with chat, history, and favorites.
|
|
242
|
-
*
|
|
243
|
-
* Supports three layout modes:
|
|
244
|
-
* - `collapsed`: Icon-only sidebar strip
|
|
245
|
-
* - `expanded`: Expandable side panel (default)
|
|
246
|
-
* - `fullPage`: Dedicated full-page view
|
|
247
|
-
*
|
|
248
|
-
* @example
|
|
249
|
-
* ```tsx
|
|
250
|
-
* // Expanded mode (default)
|
|
251
|
-
* <XerticaAssistant
|
|
252
|
-
* mode="expanded"
|
|
253
|
-
* userName="Jane Smith"
|
|
254
|
-
* onSendMessage={(msg) => console.log(msg)}
|
|
255
|
-
* />
|
|
256
|
-
*
|
|
257
|
-
* // Full-page mode
|
|
258
|
-
* <XerticaAssistant
|
|
259
|
-
* mode="fullPage"
|
|
260
|
-
* height="100vh"
|
|
261
|
-
* />
|
|
262
|
-
*
|
|
263
|
-
* // Collapsed mode (icon strip only)
|
|
264
|
-
* <XerticaAssistant
|
|
265
|
-
* mode="expanded"
|
|
266
|
-
* isExpanded={false}
|
|
267
|
-
* onToggle={() => setExpanded(!expanded)}
|
|
268
|
-
* />
|
|
269
|
-
* ```
|
|
270
|
-
*/
|
|
271
|
-
/**
|
|
272
|
-
* AI Chat Assistant component (Smart Chat Interface).
|
|
273
|
-
*
|
|
274
|
-
* @description
|
|
275
|
-
* Full-featured chat interface with support for history, favorites, attachments,
|
|
276
|
-
* and rich component rendering (tables, charts, documents, podcasts).
|
|
277
|
-
* Supports three layout modes: `'collapsed'`, `'expanded'`, and `'fullPage'`.
|
|
278
|
-
*
|
|
279
|
-
* @ai-rules
|
|
280
|
-
* 1. In `mode="expanded"` (default), the component acts as a resizable side panel.
|
|
281
|
-
* 2. Use `onSendMessage` to capture user input and `responseGenerator` to provide AI responses in demo mode.
|
|
282
|
-
* 3. Supports automatic Markdown rendering and syntax-highlighted code blocks.
|
|
283
|
-
*/
|
|
284
|
-
export function XerticaAssistant({
|
|
285
|
-
mode = 'expanded',
|
|
286
|
-
isExpanded: controlledIsExpanded,
|
|
287
|
-
onToggle,
|
|
288
|
-
defaultTab = 'chat',
|
|
289
|
-
demoMode = true,
|
|
290
|
-
onNavigateSettings,
|
|
291
|
-
onNavigateFullPage,
|
|
292
|
-
userName,
|
|
293
|
-
initialMessages = [],
|
|
294
|
-
savedConversations = [],
|
|
295
|
-
suggestions: propSuggestions,
|
|
296
|
-
onSendMessage,
|
|
297
|
-
onFileAttach,
|
|
298
|
-
isProcessing = false,
|
|
299
|
-
width,
|
|
300
|
-
height,
|
|
301
|
-
className = '',
|
|
302
|
-
mobileFloating = false,
|
|
303
|
-
customResponses = [],
|
|
304
|
-
responseGenerator,
|
|
305
|
-
richSuggestions = [],
|
|
306
|
-
welcomeMessage,
|
|
307
|
-
onRichAction,
|
|
308
|
-
onEvaluation,
|
|
309
|
-
feedbackOptions,
|
|
310
|
-
// Feature flags — all default to true for backward compatibility
|
|
311
|
-
showHistory = true,
|
|
312
|
-
showFavorites = true,
|
|
313
|
-
enableAudioInput = true,
|
|
314
|
-
enableFileAttachment = true,
|
|
315
|
-
enableDocumentCreation = true,
|
|
316
|
-
enablePodcastGeneration = true,
|
|
317
|
-
enableSearch = true,
|
|
318
|
-
}: XerticaAssistantProps) {
|
|
319
|
-
const { t } = useTranslation();
|
|
320
|
-
// Apply i18n defaults when the caller does not provide values
|
|
321
|
-
const resolvedUserName = userName ?? t('assistant.defaultUserName');
|
|
322
|
-
const resolvedWelcomeMessage = welcomeMessage ?? t('assistant.defaultWelcomeMessage');
|
|
323
|
-
// ============================================================================
|
|
324
|
-
// State & Logic — delegated to useAssistant hook
|
|
325
|
-
// ============================================================================
|
|
326
|
-
|
|
327
|
-
const {
|
|
328
|
-
isFullPage,
|
|
329
|
-
isExpanded,
|
|
330
|
-
isMobile,
|
|
331
|
-
abaSelecionada,
|
|
332
|
-
setAbaSelecionada,
|
|
333
|
-
mensagens,
|
|
334
|
-
mensagem,
|
|
335
|
-
setMensagem,
|
|
336
|
-
conversaAtual,
|
|
337
|
-
conversasFiltradas,
|
|
338
|
-
copiedId,
|
|
339
|
-
generatingPodcastId,
|
|
340
|
-
executingCommand,
|
|
341
|
-
savedSearches,
|
|
342
|
-
editingDocument,
|
|
343
|
-
setEditingDocument,
|
|
344
|
-
showMoreSuggestions,
|
|
345
|
-
setShowMoreSuggestions,
|
|
346
|
-
evaluationState,
|
|
347
|
-
setEvaluationState,
|
|
348
|
-
sugestoes,
|
|
349
|
-
messagesEndRef,
|
|
350
|
-
fileInputRef,
|
|
351
|
-
audioInputRef,
|
|
352
|
-
handleToggle,
|
|
353
|
-
handleExpandWithTab,
|
|
354
|
-
handleEnviarMensagem,
|
|
355
|
-
handleToggleFavorite,
|
|
356
|
-
handleCopyMessage,
|
|
357
|
-
handleGeneratePodcast,
|
|
358
|
-
handleDownloadDocument,
|
|
359
|
-
handleDownloadPodcast,
|
|
360
|
-
handleEditDocument,
|
|
361
|
-
handleNovaConversa,
|
|
362
|
-
handleSelecionarConversa,
|
|
363
|
-
handleToggleFavoritaConversa,
|
|
364
|
-
handleOpenSearchResult,
|
|
365
|
-
handleExecuteSearchCommand,
|
|
366
|
-
handleRichSuggestionClick,
|
|
367
|
-
handleEvaluationClick,
|
|
368
|
-
openFeedbackDialog,
|
|
369
|
-
handleSubmitDislike,
|
|
370
|
-
} = useAssistant({
|
|
371
|
-
mode,
|
|
372
|
-
isExpanded: controlledIsExpanded,
|
|
373
|
-
onToggle,
|
|
374
|
-
defaultTab,
|
|
375
|
-
demoMode,
|
|
376
|
-
customResponses,
|
|
377
|
-
initialMessages,
|
|
378
|
-
savedConversations,
|
|
379
|
-
suggestions: propSuggestions,
|
|
380
|
-
onSendMessage,
|
|
381
|
-
isProcessing,
|
|
382
|
-
responseGenerator,
|
|
383
|
-
richSuggestions,
|
|
384
|
-
onRichAction,
|
|
385
|
-
onEvaluation,
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
// ============================================================================
|
|
389
|
-
// Render
|
|
390
|
-
// ============================================================================
|
|
391
|
-
|
|
392
|
-
const containerWidth = width ?? (isFullPage ? '100%' : isExpanded ? '420px' : '80px'); // Compacto quando fechado - apenas ícones
|
|
393
|
-
const containerHeight = height ?? 'h-full';
|
|
394
|
-
|
|
395
|
-
// Mobile floating button — shown when collapsed on mobile
|
|
396
|
-
if (isMobile && !isExpanded) {
|
|
397
|
-
return (
|
|
398
|
-
<Button
|
|
399
|
-
onClick={handleToggle}
|
|
400
|
-
className={cn(
|
|
401
|
-
'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',
|
|
402
|
-
className
|
|
403
|
-
)}
|
|
404
|
-
>
|
|
405
|
-
<XerticaOrbe size={32} />
|
|
406
|
-
<span className="font-semibold text-base tracking-wide">{t('assistant.title')}</span>
|
|
407
|
-
</Button>
|
|
408
|
-
);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
return (
|
|
412
|
-
<>
|
|
413
|
-
{/* Hidden File Inputs */}
|
|
414
|
-
<input
|
|
415
|
-
ref={fileInputRef}
|
|
416
|
-
type="file"
|
|
417
|
-
accept=".pdf,.doc,.docx,.txt,.md"
|
|
418
|
-
className="hidden"
|
|
419
|
-
onChange={e => {
|
|
420
|
-
const file = e.target.files?.[0];
|
|
421
|
-
if (file && onFileAttach) {
|
|
422
|
-
onFileAttach(file);
|
|
423
|
-
}
|
|
424
|
-
}}
|
|
425
|
-
aria-label={t('assistant.uploadDocument')}
|
|
426
|
-
/>
|
|
427
|
-
<input
|
|
428
|
-
ref={audioInputRef}
|
|
429
|
-
type="file"
|
|
430
|
-
accept="audio/*"
|
|
431
|
-
className="hidden"
|
|
432
|
-
onChange={e => {
|
|
433
|
-
const file = e.target.files?.[0];
|
|
434
|
-
if (file && onFileAttach) {
|
|
435
|
-
onFileAttach(file);
|
|
436
|
-
}
|
|
437
|
-
}}
|
|
438
|
-
aria-label={t('assistant.uploadAudio')}
|
|
439
|
-
/>
|
|
440
|
-
|
|
441
|
-
{/* Main Assistant Container */}
|
|
442
|
-
<div
|
|
443
|
-
className={cn(
|
|
444
|
-
`${containerHeight} flex flex-col bg-background relative`,
|
|
445
|
-
!isFullPage && 'border-l border-border shadow-sm',
|
|
446
|
-
isMobile && isExpanded && 'fixed inset-0 z-[100] h-[100dvh] w-full border-l-0 shadow-2xl',
|
|
447
|
-
className
|
|
448
|
-
)}
|
|
449
|
-
style={
|
|
450
|
-
!(isMobile && isExpanded)
|
|
451
|
-
? {
|
|
452
|
-
width: isFullPage ? '100%' : containerWidth,
|
|
453
|
-
}
|
|
454
|
-
: undefined
|
|
455
|
-
}
|
|
456
|
-
>
|
|
457
|
-
{/* Document Editor Overlay */}
|
|
458
|
-
{editingDocument && !isFullPage && (
|
|
459
|
-
<AssistantDocumentEditor
|
|
460
|
-
document={editingDocument}
|
|
461
|
-
isMobile={isMobile}
|
|
462
|
-
containerWidth={containerWidth}
|
|
463
|
-
onClose={() => setEditingDocument(null)}
|
|
464
|
-
onChange={doc => setEditingDocument(doc)}
|
|
465
|
-
/>
|
|
466
|
-
)}
|
|
467
|
-
|
|
468
|
-
{/* Header — only visible when not in fullPage mode */}
|
|
469
|
-
{!isFullPage && (
|
|
470
|
-
<AssistantHeader
|
|
471
|
-
isExpanded={isExpanded}
|
|
472
|
-
onToggle={handleToggle}
|
|
473
|
-
onNavigateFullPage={onNavigateFullPage}
|
|
474
|
-
/>
|
|
475
|
-
)}
|
|
476
|
-
|
|
477
|
-
{/* Collapsed State — Icons Only */}
|
|
478
|
-
{!isExpanded && !isFullPage && (
|
|
479
|
-
<AssistantCollapsedView
|
|
480
|
-
showHistory={showHistory}
|
|
481
|
-
showFavorites={showFavorites}
|
|
482
|
-
onToggle={handleToggle}
|
|
483
|
-
onExpandWithTab={handleExpandWithTab}
|
|
484
|
-
/>
|
|
485
|
-
)}
|
|
486
|
-
|
|
487
|
-
{/* Expanded State — Full Content */}
|
|
488
|
-
<AnimatePresence>
|
|
489
|
-
{(isExpanded || isFullPage) && (
|
|
490
|
-
<motion.div
|
|
491
|
-
initial={isFullPage ? false : { opacity: 0, x: 50 }}
|
|
492
|
-
animate={{ opacity: 1, x: 0 }}
|
|
493
|
-
exit={isFullPage ? undefined : { opacity: 0, x: 50 }}
|
|
494
|
-
transition={{ duration: 0.2 }}
|
|
495
|
-
className="flex-1 flex flex-col overflow-hidden"
|
|
496
|
-
>
|
|
497
|
-
{/* Navigation Tabs — hidden in fullPage mode and when no secondary tabs are enabled */}
|
|
498
|
-
{!isFullPage && (showHistory || showFavorites) && (
|
|
499
|
-
<AssistantTabBar
|
|
500
|
-
activeTab={abaSelecionada}
|
|
501
|
-
showHistory={showHistory}
|
|
502
|
-
showFavorites={showFavorites}
|
|
503
|
-
onTabChange={setAbaSelecionada}
|
|
504
|
-
/>
|
|
505
|
-
)}
|
|
506
|
-
|
|
507
|
-
{/* Content Area */}
|
|
508
|
-
<div className="flex-1 overflow-hidden flex flex-col">
|
|
509
|
-
{/* Chat Tab */}
|
|
510
|
-
{abaSelecionada === 'chat' && (
|
|
511
|
-
<div
|
|
512
|
-
className={`flex-1 flex flex-col min-h-0 ${isFullPage ? 'mx-auto w-full max-w-6xl' : ''}`}
|
|
513
|
-
>
|
|
514
|
-
{mensagens.length === 0 ? (
|
|
515
|
-
<AssistantWelcomeScreen
|
|
516
|
-
userName={resolvedUserName}
|
|
517
|
-
welcomeMessage={resolvedWelcomeMessage}
|
|
518
|
-
suggestions={sugestoes}
|
|
519
|
-
richSuggestions={richSuggestions}
|
|
520
|
-
showMoreSuggestions={showMoreSuggestions}
|
|
521
|
-
onSetShowMoreSuggestions={setShowMoreSuggestions}
|
|
522
|
-
onSendSuggestion={handleEnviarMensagem}
|
|
523
|
-
onRichSuggestionClick={handleRichSuggestionClick}
|
|
524
|
-
/>
|
|
525
|
-
) : (
|
|
526
|
-
<ScrollArea className="flex-1 min-h-0 overflow-x-hidden [&_[data-radix-scroll-area-viewport]>div]:!block">
|
|
527
|
-
<div className="space-y-4 px-4 py-4 max-w-6xl mx-auto !block !w-full">
|
|
528
|
-
{mensagens.map(msg => (
|
|
529
|
-
<AssistantMessageBubble
|
|
530
|
-
key={msg.id}
|
|
531
|
-
msg={msg}
|
|
532
|
-
copiedId={copiedId}
|
|
533
|
-
generatingPodcastId={generatingPodcastId}
|
|
534
|
-
executingCommand={executingCommand}
|
|
535
|
-
savedSearches={savedSearches}
|
|
536
|
-
enablePodcastGeneration={enablePodcastGeneration}
|
|
537
|
-
feedbackOptions={feedbackOptions}
|
|
538
|
-
onCopyMessage={handleCopyMessage}
|
|
539
|
-
onToggleFavorite={handleToggleFavorite}
|
|
540
|
-
onGeneratePodcast={handleGeneratePodcast}
|
|
541
|
-
onDownloadDocument={handleDownloadDocument}
|
|
542
|
-
onDownloadPodcast={handleDownloadPodcast}
|
|
543
|
-
onEditDocument={handleEditDocument}
|
|
544
|
-
onOpenSearchResult={handleOpenSearchResult}
|
|
545
|
-
onExecuteSearchCommand={handleExecuteSearchCommand}
|
|
546
|
-
onEvaluationClick={handleEvaluationClick}
|
|
547
|
-
onOpenFeedbackDialog={openFeedbackDialog}
|
|
548
|
-
/>
|
|
549
|
-
))}
|
|
550
|
-
|
|
551
|
-
{/* Typing Indicator */}
|
|
552
|
-
{isProcessing && <AssistantTypingIndicator />}
|
|
553
|
-
|
|
554
|
-
<div ref={messagesEndRef} />
|
|
555
|
-
</div>
|
|
556
|
-
</ScrollArea>
|
|
557
|
-
)}
|
|
558
|
-
</div>
|
|
559
|
-
)}
|
|
560
|
-
|
|
561
|
-
{/* History / Favorites Tab */}
|
|
562
|
-
{((abaSelecionada === 'historico' && showHistory) ||
|
|
563
|
-
(abaSelecionada === 'favoritos' && showFavorites)) && (
|
|
564
|
-
<AssistantConversationList
|
|
565
|
-
conversations={conversasFiltradas}
|
|
566
|
-
currentConversationId={conversaAtual}
|
|
567
|
-
activeTab={abaSelecionada}
|
|
568
|
-
isFullPage={isFullPage}
|
|
569
|
-
onNewConversation={handleNovaConversa}
|
|
570
|
-
onSelectConversation={handleSelecionarConversa}
|
|
571
|
-
onToggleFavorite={handleToggleFavoritaConversa}
|
|
572
|
-
/>
|
|
573
|
-
)}
|
|
574
|
-
</div>
|
|
575
|
-
|
|
576
|
-
{/* Modern Input Area — only visible in chat mode */}
|
|
577
|
-
{abaSelecionada === 'chat' && (
|
|
578
|
-
<ModernChatInput
|
|
579
|
-
value={mensagem}
|
|
580
|
-
onChange={setMensagem}
|
|
581
|
-
onSubmit={handleEnviarMensagem}
|
|
582
|
-
onFileUpload={
|
|
583
|
-
enableFileAttachment ? () => fileInputRef.current?.click() : undefined
|
|
584
|
-
}
|
|
585
|
-
onAudioUpload={
|
|
586
|
-
enableAudioInput ? () => audioInputRef.current?.click() : undefined
|
|
587
|
-
}
|
|
588
|
-
disabled={isProcessing}
|
|
589
|
-
isFullPage={isFullPage}
|
|
590
|
-
enableAudioInput={enableAudioInput}
|
|
591
|
-
enableFileAttachment={enableFileAttachment}
|
|
592
|
-
enableDocumentCreation={enableDocumentCreation}
|
|
593
|
-
enablePodcastGeneration={enablePodcastGeneration}
|
|
594
|
-
enableSearch={enableSearch}
|
|
595
|
-
/>
|
|
596
|
-
)}
|
|
597
|
-
</motion.div>
|
|
598
|
-
)}
|
|
599
|
-
</AnimatePresence>
|
|
600
|
-
</div>
|
|
601
|
-
|
|
602
|
-
{/* Feedback Dialog */}
|
|
603
|
-
<AssistantFeedbackDialog
|
|
604
|
-
state={evaluationState}
|
|
605
|
-
onReasonChange={reason => setEvaluationState(prev => ({ ...prev, reason }))}
|
|
606
|
-
onClose={() => setEvaluationState(prev => ({ ...prev, isOpen: false }))}
|
|
607
|
-
onSubmit={handleSubmitDislike}
|
|
608
|
-
/>
|
|
609
|
-
</>
|
|
610
|
-
);
|
|
611
|
-
}
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useAssistant } from './use-assistant';
|
|
3
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { ScrollArea } from '../../ui/scroll-area';
|
|
6
|
+
import { ModernChatInput } from '../modern-chat-input';
|
|
7
|
+
import { XerticaOrbe } from '../../brand/xertica-orbe';
|
|
8
|
+
import { Button } from '../../ui/button';
|
|
9
|
+
import { cn } from '../../shared/utils';
|
|
10
|
+
|
|
11
|
+
// Sub-components
|
|
12
|
+
import {
|
|
13
|
+
AssistantCollapsedView,
|
|
14
|
+
AssistantHeader,
|
|
15
|
+
AssistantTabBar,
|
|
16
|
+
AssistantWelcomeScreen,
|
|
17
|
+
AssistantMessageBubble,
|
|
18
|
+
AssistantTypingIndicator,
|
|
19
|
+
AssistantConversationList,
|
|
20
|
+
AssistantFeedbackDialog,
|
|
21
|
+
AssistantDocumentEditor,
|
|
22
|
+
} from './parts';
|
|
23
|
+
import type { EvaluationState } from './parts';
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// TypeScript Interfaces & Types — imported from shared types.ts and re-exported
|
|
27
|
+
// for backward compatibility with consumers that import from xertica-assistant.
|
|
28
|
+
// ============================================================================
|
|
29
|
+
import type {
|
|
30
|
+
MessageType,
|
|
31
|
+
AttachmentType,
|
|
32
|
+
SearchResultType,
|
|
33
|
+
AssistantMode,
|
|
34
|
+
AssistantTab,
|
|
35
|
+
SearchResult,
|
|
36
|
+
SearchSource,
|
|
37
|
+
SearchCommand,
|
|
38
|
+
Message,
|
|
39
|
+
Conversation,
|
|
40
|
+
Suggestion,
|
|
41
|
+
MockResponse,
|
|
42
|
+
} from './types';
|
|
43
|
+
|
|
44
|
+
export type {
|
|
45
|
+
MessageType,
|
|
46
|
+
AttachmentType,
|
|
47
|
+
SearchResultType,
|
|
48
|
+
AssistantMode,
|
|
49
|
+
AssistantTab,
|
|
50
|
+
SearchResult,
|
|
51
|
+
SearchSource,
|
|
52
|
+
SearchCommand,
|
|
53
|
+
Message,
|
|
54
|
+
Conversation,
|
|
55
|
+
Suggestion,
|
|
56
|
+
MockResponse,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Component Props
|
|
61
|
+
// ============================================================================
|
|
62
|
+
|
|
63
|
+
export interface XerticaAssistantProps {
|
|
64
|
+
/**
|
|
65
|
+
* Layout mode for the assistant panel
|
|
66
|
+
* @default 'expanded'
|
|
67
|
+
*/
|
|
68
|
+
mode?: AssistantMode;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Whether the panel is expanded (only applies when `mode='expanded'`)
|
|
72
|
+
* @default true
|
|
73
|
+
*/
|
|
74
|
+
isExpanded?: boolean;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Callback fired when the assistant panel is expanded or collapsed
|
|
78
|
+
*/
|
|
79
|
+
onToggle?: () => void;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Initially selected tab
|
|
83
|
+
* @default 'chat'
|
|
84
|
+
*/
|
|
85
|
+
defaultTab?: AssistantTab;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Enables demo mode — generates mock AI responses without a real API key
|
|
89
|
+
*/
|
|
90
|
+
demoMode?: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Custom mock responses to use in demo mode
|
|
94
|
+
*/
|
|
95
|
+
customResponses?: MockResponse[];
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Callback fired when the user navigates to the settings page
|
|
99
|
+
*/
|
|
100
|
+
onNavigateSettings?: () => void;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Callback fired when the user navigates to the full-page assistant view
|
|
104
|
+
*/
|
|
105
|
+
onNavigateFullPage?: () => void;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Display name of the logged-in user
|
|
109
|
+
* @default 'User'
|
|
110
|
+
*/
|
|
111
|
+
userName?: string;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Pre-loaded messages to hydrate an existing conversation
|
|
115
|
+
*/
|
|
116
|
+
initialMessages?: Message[];
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Previously saved conversations shown in the history panel
|
|
120
|
+
*/
|
|
121
|
+
savedConversations?: Conversation[];
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Suggested prompts shown to the user in the empty state
|
|
125
|
+
*/
|
|
126
|
+
suggestions?: Suggestion[];
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Subtitle shown below the user's name in the empty state.
|
|
130
|
+
* @default 'Como posso ajudar?'
|
|
131
|
+
*/
|
|
132
|
+
welcomeMessage?: string;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Callback fired when the user sends a message
|
|
136
|
+
*/
|
|
137
|
+
onSendMessage?: (message: string) => void;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Callback fired when the user attaches a file
|
|
141
|
+
*/
|
|
142
|
+
onFileAttach?: (file: File) => void;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* If true, shows a typing indicator while waiting for an AI response
|
|
146
|
+
*/
|
|
147
|
+
isProcessing?: boolean;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Custom panel width (only applies when `mode='expanded'`)
|
|
151
|
+
*/
|
|
152
|
+
width?: string;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Custom panel height (only applies when `mode='fullPage'`)
|
|
156
|
+
*/
|
|
157
|
+
height?: string;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Additional CSS classes for the root container
|
|
161
|
+
*/
|
|
162
|
+
className?: string;
|
|
163
|
+
mobileFloating?: boolean;
|
|
164
|
+
/**
|
|
165
|
+
* Custom response generator function — overrides demo mode defaults
|
|
166
|
+
* @param message The user's input message
|
|
167
|
+
* @returns A promise or direct value resolving to either a markdown string or a partial `Message` object
|
|
168
|
+
*/
|
|
169
|
+
responseGenerator?: (
|
|
170
|
+
message: string
|
|
171
|
+
) => Promise<string | Partial<Message>> | string | Partial<Message>;
|
|
172
|
+
/**
|
|
173
|
+
* Extended suggestions shown when the user clicks "More suggestions"
|
|
174
|
+
*/
|
|
175
|
+
richSuggestions?: Suggestion[];
|
|
176
|
+
/**
|
|
177
|
+
* Callback fired when the user clicks a rich suggestion item
|
|
178
|
+
*/
|
|
179
|
+
onRichAction?: (actionId: string, actionText: string) => void;
|
|
180
|
+
/**
|
|
181
|
+
* Callback fired when the user rates a message (thumbs up/down)
|
|
182
|
+
*/
|
|
183
|
+
onEvaluation?: (messageId: string, type: 'like' | 'dislike', reason?: string) => void;
|
|
184
|
+
/**
|
|
185
|
+
* Negative feedback categories shown in the dislike dropdown
|
|
186
|
+
*/
|
|
187
|
+
feedbackOptions?: string[];
|
|
188
|
+
|
|
189
|
+
// ============================================================================
|
|
190
|
+
// Feature Flags — Controls individual assistant capabilities
|
|
191
|
+
// ============================================================================
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Whether to show the conversation history tab and collapsed icon.
|
|
195
|
+
* @default true
|
|
196
|
+
*/
|
|
197
|
+
showHistory?: boolean;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Whether to show the favorites tab and collapsed icon.
|
|
201
|
+
* @default true
|
|
202
|
+
*/
|
|
203
|
+
showFavorites?: boolean;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Whether to enable audio input (voice recording / audio upload) in the chat.
|
|
207
|
+
* @default true
|
|
208
|
+
*/
|
|
209
|
+
enableAudioInput?: boolean;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Whether to enable file attachment in the chat input.
|
|
213
|
+
* @default true
|
|
214
|
+
*/
|
|
215
|
+
enableFileAttachment?: boolean;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Whether to enable the "Create document" action in the chat input.
|
|
219
|
+
* @default true
|
|
220
|
+
*/
|
|
221
|
+
enableDocumentCreation?: boolean;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Whether to enable podcast generation (action chip + per-message button).
|
|
225
|
+
* @default true
|
|
226
|
+
*/
|
|
227
|
+
enablePodcastGeneration?: boolean;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Whether to enable the "Search" action in the chat input.
|
|
231
|
+
* @default true
|
|
232
|
+
*/
|
|
233
|
+
enableSearch?: boolean;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ============================================================================
|
|
237
|
+
// Main Component
|
|
238
|
+
// ============================================================================
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* XerticaAssistant - Full-featured AI assistant with chat, history, and favorites.
|
|
242
|
+
*
|
|
243
|
+
* Supports three layout modes:
|
|
244
|
+
* - `collapsed`: Icon-only sidebar strip
|
|
245
|
+
* - `expanded`: Expandable side panel (default)
|
|
246
|
+
* - `fullPage`: Dedicated full-page view
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```tsx
|
|
250
|
+
* // Expanded mode (default)
|
|
251
|
+
* <XerticaAssistant
|
|
252
|
+
* mode="expanded"
|
|
253
|
+
* userName="Jane Smith"
|
|
254
|
+
* onSendMessage={(msg) => console.log(msg)}
|
|
255
|
+
* />
|
|
256
|
+
*
|
|
257
|
+
* // Full-page mode
|
|
258
|
+
* <XerticaAssistant
|
|
259
|
+
* mode="fullPage"
|
|
260
|
+
* height="100vh"
|
|
261
|
+
* />
|
|
262
|
+
*
|
|
263
|
+
* // Collapsed mode (icon strip only)
|
|
264
|
+
* <XerticaAssistant
|
|
265
|
+
* mode="expanded"
|
|
266
|
+
* isExpanded={false}
|
|
267
|
+
* onToggle={() => setExpanded(!expanded)}
|
|
268
|
+
* />
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
/**
|
|
272
|
+
* AI Chat Assistant component (Smart Chat Interface).
|
|
273
|
+
*
|
|
274
|
+
* @description
|
|
275
|
+
* Full-featured chat interface with support for history, favorites, attachments,
|
|
276
|
+
* and rich component rendering (tables, charts, documents, podcasts).
|
|
277
|
+
* Supports three layout modes: `'collapsed'`, `'expanded'`, and `'fullPage'`.
|
|
278
|
+
*
|
|
279
|
+
* @ai-rules
|
|
280
|
+
* 1. In `mode="expanded"` (default), the component acts as a resizable side panel.
|
|
281
|
+
* 2. Use `onSendMessage` to capture user input and `responseGenerator` to provide AI responses in demo mode.
|
|
282
|
+
* 3. Supports automatic Markdown rendering and syntax-highlighted code blocks.
|
|
283
|
+
*/
|
|
284
|
+
export function XerticaAssistant({
|
|
285
|
+
mode = 'expanded',
|
|
286
|
+
isExpanded: controlledIsExpanded,
|
|
287
|
+
onToggle,
|
|
288
|
+
defaultTab = 'chat',
|
|
289
|
+
demoMode = true,
|
|
290
|
+
onNavigateSettings,
|
|
291
|
+
onNavigateFullPage,
|
|
292
|
+
userName,
|
|
293
|
+
initialMessages = [],
|
|
294
|
+
savedConversations = [],
|
|
295
|
+
suggestions: propSuggestions,
|
|
296
|
+
onSendMessage,
|
|
297
|
+
onFileAttach,
|
|
298
|
+
isProcessing = false,
|
|
299
|
+
width,
|
|
300
|
+
height,
|
|
301
|
+
className = '',
|
|
302
|
+
mobileFloating = false,
|
|
303
|
+
customResponses = [],
|
|
304
|
+
responseGenerator,
|
|
305
|
+
richSuggestions = [],
|
|
306
|
+
welcomeMessage,
|
|
307
|
+
onRichAction,
|
|
308
|
+
onEvaluation,
|
|
309
|
+
feedbackOptions,
|
|
310
|
+
// Feature flags — all default to true for backward compatibility
|
|
311
|
+
showHistory = true,
|
|
312
|
+
showFavorites = true,
|
|
313
|
+
enableAudioInput = true,
|
|
314
|
+
enableFileAttachment = true,
|
|
315
|
+
enableDocumentCreation = true,
|
|
316
|
+
enablePodcastGeneration = true,
|
|
317
|
+
enableSearch = true,
|
|
318
|
+
}: XerticaAssistantProps) {
|
|
319
|
+
const { t } = useTranslation();
|
|
320
|
+
// Apply i18n defaults when the caller does not provide values
|
|
321
|
+
const resolvedUserName = userName ?? t('assistant.defaultUserName');
|
|
322
|
+
const resolvedWelcomeMessage = welcomeMessage ?? t('assistant.defaultWelcomeMessage');
|
|
323
|
+
// ============================================================================
|
|
324
|
+
// State & Logic — delegated to useAssistant hook
|
|
325
|
+
// ============================================================================
|
|
326
|
+
|
|
327
|
+
const {
|
|
328
|
+
isFullPage,
|
|
329
|
+
isExpanded,
|
|
330
|
+
isMobile,
|
|
331
|
+
abaSelecionada,
|
|
332
|
+
setAbaSelecionada,
|
|
333
|
+
mensagens,
|
|
334
|
+
mensagem,
|
|
335
|
+
setMensagem,
|
|
336
|
+
conversaAtual,
|
|
337
|
+
conversasFiltradas,
|
|
338
|
+
copiedId,
|
|
339
|
+
generatingPodcastId,
|
|
340
|
+
executingCommand,
|
|
341
|
+
savedSearches,
|
|
342
|
+
editingDocument,
|
|
343
|
+
setEditingDocument,
|
|
344
|
+
showMoreSuggestions,
|
|
345
|
+
setShowMoreSuggestions,
|
|
346
|
+
evaluationState,
|
|
347
|
+
setEvaluationState,
|
|
348
|
+
sugestoes,
|
|
349
|
+
messagesEndRef,
|
|
350
|
+
fileInputRef,
|
|
351
|
+
audioInputRef,
|
|
352
|
+
handleToggle,
|
|
353
|
+
handleExpandWithTab,
|
|
354
|
+
handleEnviarMensagem,
|
|
355
|
+
handleToggleFavorite,
|
|
356
|
+
handleCopyMessage,
|
|
357
|
+
handleGeneratePodcast,
|
|
358
|
+
handleDownloadDocument,
|
|
359
|
+
handleDownloadPodcast,
|
|
360
|
+
handleEditDocument,
|
|
361
|
+
handleNovaConversa,
|
|
362
|
+
handleSelecionarConversa,
|
|
363
|
+
handleToggleFavoritaConversa,
|
|
364
|
+
handleOpenSearchResult,
|
|
365
|
+
handleExecuteSearchCommand,
|
|
366
|
+
handleRichSuggestionClick,
|
|
367
|
+
handleEvaluationClick,
|
|
368
|
+
openFeedbackDialog,
|
|
369
|
+
handleSubmitDislike,
|
|
370
|
+
} = useAssistant({
|
|
371
|
+
mode,
|
|
372
|
+
isExpanded: controlledIsExpanded,
|
|
373
|
+
onToggle,
|
|
374
|
+
defaultTab,
|
|
375
|
+
demoMode,
|
|
376
|
+
customResponses,
|
|
377
|
+
initialMessages,
|
|
378
|
+
savedConversations,
|
|
379
|
+
suggestions: propSuggestions,
|
|
380
|
+
onSendMessage,
|
|
381
|
+
isProcessing,
|
|
382
|
+
responseGenerator,
|
|
383
|
+
richSuggestions,
|
|
384
|
+
onRichAction,
|
|
385
|
+
onEvaluation,
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
// ============================================================================
|
|
389
|
+
// Render
|
|
390
|
+
// ============================================================================
|
|
391
|
+
|
|
392
|
+
const containerWidth = width ?? (isFullPage ? '100%' : isExpanded ? '420px' : '80px'); // Compacto quando fechado - apenas ícones
|
|
393
|
+
const containerHeight = height ?? 'h-full';
|
|
394
|
+
|
|
395
|
+
// Mobile floating button — shown when collapsed on mobile
|
|
396
|
+
if (isMobile && !isExpanded) {
|
|
397
|
+
return (
|
|
398
|
+
<Button
|
|
399
|
+
onClick={handleToggle}
|
|
400
|
+
className={cn(
|
|
401
|
+
'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',
|
|
402
|
+
className
|
|
403
|
+
)}
|
|
404
|
+
>
|
|
405
|
+
<XerticaOrbe size={32} />
|
|
406
|
+
<span className="font-semibold text-base tracking-wide">{t('assistant.title')}</span>
|
|
407
|
+
</Button>
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return (
|
|
412
|
+
<>
|
|
413
|
+
{/* Hidden File Inputs */}
|
|
414
|
+
<input
|
|
415
|
+
ref={fileInputRef}
|
|
416
|
+
type="file"
|
|
417
|
+
accept=".pdf,.doc,.docx,.txt,.md"
|
|
418
|
+
className="hidden"
|
|
419
|
+
onChange={e => {
|
|
420
|
+
const file = e.target.files?.[0];
|
|
421
|
+
if (file && onFileAttach) {
|
|
422
|
+
onFileAttach(file);
|
|
423
|
+
}
|
|
424
|
+
}}
|
|
425
|
+
aria-label={t('assistant.uploadDocument')}
|
|
426
|
+
/>
|
|
427
|
+
<input
|
|
428
|
+
ref={audioInputRef}
|
|
429
|
+
type="file"
|
|
430
|
+
accept="audio/*"
|
|
431
|
+
className="hidden"
|
|
432
|
+
onChange={e => {
|
|
433
|
+
const file = e.target.files?.[0];
|
|
434
|
+
if (file && onFileAttach) {
|
|
435
|
+
onFileAttach(file);
|
|
436
|
+
}
|
|
437
|
+
}}
|
|
438
|
+
aria-label={t('assistant.uploadAudio')}
|
|
439
|
+
/>
|
|
440
|
+
|
|
441
|
+
{/* Main Assistant Container */}
|
|
442
|
+
<div
|
|
443
|
+
className={cn(
|
|
444
|
+
`${containerHeight} flex flex-col bg-background relative`,
|
|
445
|
+
!isFullPage && 'border-l border-border shadow-sm',
|
|
446
|
+
isMobile && isExpanded && 'fixed inset-0 z-[100] h-[100dvh] w-full border-l-0 shadow-2xl',
|
|
447
|
+
className
|
|
448
|
+
)}
|
|
449
|
+
style={
|
|
450
|
+
!(isMobile && isExpanded)
|
|
451
|
+
? {
|
|
452
|
+
width: isFullPage ? '100%' : containerWidth,
|
|
453
|
+
}
|
|
454
|
+
: undefined
|
|
455
|
+
}
|
|
456
|
+
>
|
|
457
|
+
{/* Document Editor Overlay */}
|
|
458
|
+
{editingDocument && !isFullPage && (
|
|
459
|
+
<AssistantDocumentEditor
|
|
460
|
+
document={editingDocument}
|
|
461
|
+
isMobile={isMobile}
|
|
462
|
+
containerWidth={containerWidth}
|
|
463
|
+
onClose={() => setEditingDocument(null)}
|
|
464
|
+
onChange={doc => setEditingDocument(doc)}
|
|
465
|
+
/>
|
|
466
|
+
)}
|
|
467
|
+
|
|
468
|
+
{/* Header — only visible when not in fullPage mode */}
|
|
469
|
+
{!isFullPage && (
|
|
470
|
+
<AssistantHeader
|
|
471
|
+
isExpanded={isExpanded}
|
|
472
|
+
onToggle={handleToggle}
|
|
473
|
+
onNavigateFullPage={onNavigateFullPage}
|
|
474
|
+
/>
|
|
475
|
+
)}
|
|
476
|
+
|
|
477
|
+
{/* Collapsed State — Icons Only */}
|
|
478
|
+
{!isExpanded && !isFullPage && (
|
|
479
|
+
<AssistantCollapsedView
|
|
480
|
+
showHistory={showHistory}
|
|
481
|
+
showFavorites={showFavorites}
|
|
482
|
+
onToggle={handleToggle}
|
|
483
|
+
onExpandWithTab={handleExpandWithTab}
|
|
484
|
+
/>
|
|
485
|
+
)}
|
|
486
|
+
|
|
487
|
+
{/* Expanded State — Full Content */}
|
|
488
|
+
<AnimatePresence>
|
|
489
|
+
{(isExpanded || isFullPage) && (
|
|
490
|
+
<motion.div
|
|
491
|
+
initial={isFullPage ? false : { opacity: 0, x: 50 }}
|
|
492
|
+
animate={{ opacity: 1, x: 0 }}
|
|
493
|
+
exit={isFullPage ? undefined : { opacity: 0, x: 50 }}
|
|
494
|
+
transition={{ duration: 0.2 }}
|
|
495
|
+
className="flex-1 flex flex-col overflow-hidden"
|
|
496
|
+
>
|
|
497
|
+
{/* Navigation Tabs — hidden in fullPage mode and when no secondary tabs are enabled */}
|
|
498
|
+
{!isFullPage && (showHistory || showFavorites) && (
|
|
499
|
+
<AssistantTabBar
|
|
500
|
+
activeTab={abaSelecionada}
|
|
501
|
+
showHistory={showHistory}
|
|
502
|
+
showFavorites={showFavorites}
|
|
503
|
+
onTabChange={setAbaSelecionada}
|
|
504
|
+
/>
|
|
505
|
+
)}
|
|
506
|
+
|
|
507
|
+
{/* Content Area */}
|
|
508
|
+
<div className="flex-1 overflow-hidden flex flex-col">
|
|
509
|
+
{/* Chat Tab */}
|
|
510
|
+
{abaSelecionada === 'chat' && (
|
|
511
|
+
<div
|
|
512
|
+
className={`flex-1 flex flex-col min-h-0 ${isFullPage ? 'mx-auto w-full max-w-6xl' : ''}`}
|
|
513
|
+
>
|
|
514
|
+
{mensagens.length === 0 ? (
|
|
515
|
+
<AssistantWelcomeScreen
|
|
516
|
+
userName={resolvedUserName}
|
|
517
|
+
welcomeMessage={resolvedWelcomeMessage}
|
|
518
|
+
suggestions={sugestoes}
|
|
519
|
+
richSuggestions={richSuggestions}
|
|
520
|
+
showMoreSuggestions={showMoreSuggestions}
|
|
521
|
+
onSetShowMoreSuggestions={setShowMoreSuggestions}
|
|
522
|
+
onSendSuggestion={handleEnviarMensagem}
|
|
523
|
+
onRichSuggestionClick={handleRichSuggestionClick}
|
|
524
|
+
/>
|
|
525
|
+
) : (
|
|
526
|
+
<ScrollArea className="flex-1 min-h-0 overflow-x-hidden [&_[data-radix-scroll-area-viewport]>div]:!block">
|
|
527
|
+
<div className="space-y-4 px-4 py-4 max-w-6xl mx-auto !block !w-full">
|
|
528
|
+
{mensagens.map(msg => (
|
|
529
|
+
<AssistantMessageBubble
|
|
530
|
+
key={msg.id}
|
|
531
|
+
msg={msg}
|
|
532
|
+
copiedId={copiedId}
|
|
533
|
+
generatingPodcastId={generatingPodcastId}
|
|
534
|
+
executingCommand={executingCommand}
|
|
535
|
+
savedSearches={savedSearches}
|
|
536
|
+
enablePodcastGeneration={enablePodcastGeneration}
|
|
537
|
+
feedbackOptions={feedbackOptions}
|
|
538
|
+
onCopyMessage={handleCopyMessage}
|
|
539
|
+
onToggleFavorite={handleToggleFavorite}
|
|
540
|
+
onGeneratePodcast={handleGeneratePodcast}
|
|
541
|
+
onDownloadDocument={handleDownloadDocument}
|
|
542
|
+
onDownloadPodcast={handleDownloadPodcast}
|
|
543
|
+
onEditDocument={handleEditDocument}
|
|
544
|
+
onOpenSearchResult={handleOpenSearchResult}
|
|
545
|
+
onExecuteSearchCommand={handleExecuteSearchCommand}
|
|
546
|
+
onEvaluationClick={handleEvaluationClick}
|
|
547
|
+
onOpenFeedbackDialog={openFeedbackDialog}
|
|
548
|
+
/>
|
|
549
|
+
))}
|
|
550
|
+
|
|
551
|
+
{/* Typing Indicator */}
|
|
552
|
+
{isProcessing && <AssistantTypingIndicator />}
|
|
553
|
+
|
|
554
|
+
<div ref={messagesEndRef} />
|
|
555
|
+
</div>
|
|
556
|
+
</ScrollArea>
|
|
557
|
+
)}
|
|
558
|
+
</div>
|
|
559
|
+
)}
|
|
560
|
+
|
|
561
|
+
{/* History / Favorites Tab */}
|
|
562
|
+
{((abaSelecionada === 'historico' && showHistory) ||
|
|
563
|
+
(abaSelecionada === 'favoritos' && showFavorites)) && (
|
|
564
|
+
<AssistantConversationList
|
|
565
|
+
conversations={conversasFiltradas}
|
|
566
|
+
currentConversationId={conversaAtual}
|
|
567
|
+
activeTab={abaSelecionada}
|
|
568
|
+
isFullPage={isFullPage}
|
|
569
|
+
onNewConversation={handleNovaConversa}
|
|
570
|
+
onSelectConversation={handleSelecionarConversa}
|
|
571
|
+
onToggleFavorite={handleToggleFavoritaConversa}
|
|
572
|
+
/>
|
|
573
|
+
)}
|
|
574
|
+
</div>
|
|
575
|
+
|
|
576
|
+
{/* Modern Input Area — only visible in chat mode */}
|
|
577
|
+
{abaSelecionada === 'chat' && (
|
|
578
|
+
<ModernChatInput
|
|
579
|
+
value={mensagem}
|
|
580
|
+
onChange={setMensagem}
|
|
581
|
+
onSubmit={handleEnviarMensagem}
|
|
582
|
+
onFileUpload={
|
|
583
|
+
enableFileAttachment ? () => fileInputRef.current?.click() : undefined
|
|
584
|
+
}
|
|
585
|
+
onAudioUpload={
|
|
586
|
+
enableAudioInput ? () => audioInputRef.current?.click() : undefined
|
|
587
|
+
}
|
|
588
|
+
disabled={isProcessing}
|
|
589
|
+
isFullPage={isFullPage}
|
|
590
|
+
enableAudioInput={enableAudioInput}
|
|
591
|
+
enableFileAttachment={enableFileAttachment}
|
|
592
|
+
enableDocumentCreation={enableDocumentCreation}
|
|
593
|
+
enablePodcastGeneration={enablePodcastGeneration}
|
|
594
|
+
enableSearch={enableSearch}
|
|
595
|
+
/>
|
|
596
|
+
)}
|
|
597
|
+
</motion.div>
|
|
598
|
+
)}
|
|
599
|
+
</AnimatePresence>
|
|
600
|
+
</div>
|
|
601
|
+
|
|
602
|
+
{/* Feedback Dialog */}
|
|
603
|
+
<AssistantFeedbackDialog
|
|
604
|
+
state={evaluationState}
|
|
605
|
+
onReasonChange={reason => setEvaluationState(prev => ({ ...prev, reason }))}
|
|
606
|
+
onClose={() => setEvaluationState(prev => ({ ...prev, isOpen: false }))}
|
|
607
|
+
onSubmit={handleSubmitDislike}
|
|
608
|
+
/>
|
|
609
|
+
</>
|
|
610
|
+
);
|
|
611
|
+
}
|