xertica-ui 2.1.3 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +1 -1
- package/assets/xertica-logo.svg +37 -37
- package/assets/xertica-x-logo.svg +20 -20
- package/components/assistant/index.ts +6 -6
- package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +97 -0
- package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -0
- package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -0
- package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +86 -0
- package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +77 -0
- package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +573 -0
- package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +65 -0
- package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -0
- package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +98 -0
- package/components/assistant/xertica-assistant/parts/index.ts +16 -0
- package/components/assistant/xertica-assistant/types.ts +139 -0
- package/components/assistant/xertica-assistant/use-assistant.ts +5 -10
- package/components/assistant/xertica-assistant/xertica-assistant.tsx +125 -1096
- package/components/blocks/card-patterns/ActivityCard.tsx +72 -72
- package/components/blocks/card-patterns/FeatureCard.tsx +100 -100
- package/components/blocks/card-patterns/NotificationCard.tsx +127 -127
- package/components/blocks/card-patterns/ProfileCard.tsx +84 -84
- package/components/blocks/card-patterns/ProjectCard.tsx +89 -89
- package/components/blocks/card-patterns/QuickActionCard.tsx +62 -62
- package/components/blocks/card-patterns/card-patterns.stories.tsx +445 -445
- package/components/blocks/card-patterns/index.ts +17 -17
- package/components/blocks/index.ts +1 -1
- package/components/brand/index.ts +6 -6
- package/components/brand/theme-toggle/ThemeToggle.tsx +8 -27
- package/components/brand/xertica-provider/XerticaProvider.tsx +48 -48
- package/components/brand/xertica-provider/xertica-provider.mdx +61 -61
- package/components/brand/xertica-provider/xertica-provider.test.tsx +52 -52
- package/components/examples/MapExamples.tsx +282 -282
- package/components/examples/SimpleFilterableMap.tsx +191 -191
- package/components/examples/index.ts +51 -51
- package/components/figma/ImageWithFallback.tsx +27 -27
- package/components/hooks/index.ts +10 -7
- package/components/hooks/use-layout-shortcuts.ts +46 -0
- package/components/index.ts +5 -5
- package/components/layout/header/header.test.tsx +8 -8
- package/components/layout/header/header.tsx +4 -4
- package/components/layout/index.ts +2 -2
- package/components/layout/sidebar/sidebar.mdx +1 -1
- package/components/layout/sidebar/sidebar.test.tsx +11 -11
- package/components/layout/sidebar/sidebar.tsx +1 -31
- package/components/layout/sidebar/use-sidebar.ts +2 -11
- package/components/media/FloatingMediaWrapper.tsx +11 -11
- package/components/media/audio-player/AudioPlayer.tsx +140 -215
- package/components/media/audio-player/use-audio-player.ts +298 -0
- package/components/media/index.ts +3 -3
- package/components/pages/home-content/HomeContent.tsx +7 -7
- package/components/pages/home-content/home-content.mdx +62 -62
- package/components/pages/home-page/HomePage.stories.tsx +39 -39
- package/components/pages/home-page/home-page.mdx +53 -53
- package/components/pages/index.ts +8 -8
- package/components/pages/template-content/template-content.mdx +61 -61
- package/components/pages/template-page/TemplatePage.stories.tsx +39 -39
- package/components/pages/template-page/template-page.mdx +53 -53
- package/components/public-api-smoke.test.tsx +52 -52
- package/components/shared/CustomTooltipContent.tsx +52 -0
- package/components/shared/assistant-utils.ts +43 -43
- package/components/ui/accordion/accordion.mdx +8 -8
- package/components/ui/accordion/accordion.stories.tsx +53 -53
- 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/badge/badge.tsx +9 -9
- 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/calendar/calendar.tsx +258 -258
- package/components/ui/card/card.mdx +8 -8
- package/components/ui/card/card.stories.tsx +245 -245
- package/components/ui/carousel/carousel.mdx +8 -8
- package/components/ui/chart/chart.mdx +8 -8
- package/components/ui/chart/chart.stories.tsx +1303 -1303
- package/components/ui/chart/chart.test.tsx +154 -154
- package/components/ui/chart/chart.tsx +2367 -2367
- package/components/ui/checkbox/checkbox.mdx +8 -8
- package/components/ui/checkbox/checkbox.stories.tsx +20 -20
- 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/google-maps-loader/google-maps-loader.tsx +2 -2
- 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/input-otp/input-otp.stories.tsx +6 -6
- package/components/ui/label/label.mdx +8 -8
- package/components/ui/map/map.mdx +8 -8
- package/components/ui/map/map.stories.tsx +51 -51
- package/components/ui/map/map.tsx +2 -2
- 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/progress/progress.tsx +68 -68
- 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/route-map/route-map.stories.tsx +54 -54
- package/components/ui/route-map/route-map.tsx +2 -2
- 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/select/select.stories.tsx +9 -9
- package/components/ui/separator/separator.mdx +8 -8
- package/components/ui/sheet/sheet.mdx +8 -8
- package/components/ui/sheet/sheet.stories.tsx +95 -95
- package/components/ui/simple-map/simple-map.mdx +8 -8
- package/components/ui/simple-map/simple-map.stories.tsx +48 -48
- 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/stats-card.mdx +8 -8
- package/components/ui/stepper/stepper.mdx +8 -8
- package/components/ui/switch/switch.mdx +8 -8
- package/components/ui/switch/switch.stories.tsx +20 -20
- package/components/ui/table/table.mdx +8 -8
- package/components/ui/tabs/tabs.mdx +8 -8
- package/components/ui/tabs/tabs.stories.tsx +26 -26
- 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 +1512 -1512
- package/contexts/ApiKeyContext.tsx +72 -72
- package/contexts/AssistenteContext.tsx +17 -54
- package/contexts/BrandColorsContext.tsx +32 -43
- package/contexts/LanguageContext.tsx +13 -13
- package/contexts/LayoutContext.test.tsx +11 -11
- package/contexts/LayoutContext.tsx +24 -50
- package/contexts/ThemeContext.tsx +26 -26
- package/contexts/theme-data.ts +4 -4
- package/dist/{AssistantChart-DoZCyS5r.cjs → AssistantChart-9w31gdAb.cjs} +4 -4
- package/dist/{AssistantChart-CldVCVDe.cjs → AssistantChart-BAudAfne.cjs} +5 -5
- package/dist/{use-mobile-DRB3BQgD.cjs → AssistantChart-BAx9VQvb.cjs} +209 -1070
- package/dist/{AssistantChart-Cu3m7RBo.js → AssistantChart-BP8upjMk.js} +5 -5
- package/dist/{use-mobile-BvYdisLP.js → AssistantChart-CVko2A1W.js} +171 -1025
- package/dist/{AssistantChart-C_hwFRRr.js → AssistantChart-CVzmmhx4.js} +4 -4
- package/dist/{AudioPlayer-C12BjQBV.cjs → AudioPlayer-1ypwE2Wh.cjs} +126 -187
- package/dist/{AudioPlayer-DcFKRJE_.js → AudioPlayer-DuKXrCfy.js} +80 -141
- package/dist/CustomTooltipContent-DHjkY0ww.js +40 -0
- package/dist/CustomTooltipContent-c_K-DWRr.cjs +56 -0
- package/dist/{ThemeContext-BoH4NLfN.js → LanguageContext-BwhwC3G2.js} +27 -104
- package/dist/{ThemeContext-r69W20Xg.cjs → LanguageContext-DvUt5jBg.cjs} +27 -104
- package/dist/{LayoutContext-BvK-ggDa.cjs → LayoutContext-BDmcZfMH.cjs} +8 -20
- package/dist/{LayoutContext-BAql6ZRY.js → LayoutContext-dbQvdC4O.js} +8 -20
- package/dist/{ThemeContext-C2EwAPDt.js → ThemeContext-BbBNoFTG.js} +2 -2
- package/dist/{ThemeContext-vTjumZeM.cjs → ThemeContext-Cmr8Ex8H.cjs} +2 -2
- package/dist/ThemeContext-RTy1m2Uq.js +82 -0
- package/dist/ThemeContext-bSzuOit2.cjs +81 -0
- package/dist/VerifyEmailPage-BE-L9mB7.js +2828 -0
- package/dist/{VerifyEmailPage-Cwi3kbol.cjs → VerifyEmailPage-Bae2cBXT.cjs} +7 -7
- package/dist/VerifyEmailPage-CR7kb5df.cjs +2827 -0
- package/dist/{VerifyEmailPage-C0c2e5n0.js → VerifyEmailPage-C_ihbcth.js} +6 -6
- package/dist/VerifyEmailPage-CbgjOF0v.js +2828 -0
- package/dist/{VerifyEmailPage-DvMLZgFt.js → VerifyEmailPage-CdYPSJoO.js} +1 -1
- package/dist/{VerifyEmailPage-CYXtbKi3.cjs → VerifyEmailPage-DMBh4NM9.cjs} +1 -1
- package/dist/VerifyEmailPage-Dt7zgA4w.cjs +2827 -0
- package/dist/{XerticaProvider-CEoWMTxu.js → XerticaProvider-BITjgC5p.js} +2 -2
- package/dist/{XerticaProvider-CllrbMEJ.cjs → XerticaProvider-By8q3Roe.cjs} +2 -2
- package/dist/{XerticaProvider-cI9hSs27.cjs → XerticaProvider-CW9hpCdF.cjs} +9 -8
- package/dist/{XerticaProvider-DDuiIcKo.js → XerticaProvider-siSt9uG2.js} +5 -4
- package/dist/{LanguageSelector-D6uacAIM.cjs → XerticaXLogo-D8jf0SNv.cjs} +86 -102
- package/dist/{LanguageSelector-B5YfbHra.js → XerticaXLogo-fAJMy3H4.js} +87 -103
- 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/assistant.cjs.js +1 -1
- package/dist/assistant.es.js +1 -1
- package/dist/brand.cjs.js +2 -2
- package/dist/brand.es.js +2 -2
- package/dist/components/assistant/xertica-assistant/parts/AssistantCollapsedView.d.ts +13 -0
- package/dist/components/assistant/xertica-assistant/parts/AssistantConversationList.d.ts +16 -0
- package/dist/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.d.ts +17 -0
- package/dist/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.d.ts +19 -0
- package/dist/components/assistant/xertica-assistant/parts/AssistantHeader.d.ts +11 -0
- package/dist/components/assistant/xertica-assistant/parts/AssistantMessageBubble.d.ts +29 -0
- package/dist/components/assistant/xertica-assistant/parts/AssistantTabBar.d.ts +13 -0
- package/dist/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.d.ts +4 -0
- package/dist/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.d.ts +17 -0
- package/dist/components/assistant/xertica-assistant/parts/index.d.ts +16 -0
- package/dist/components/assistant/xertica-assistant/types.d.ts +106 -0
- package/dist/components/assistant/xertica-assistant/use-assistant.d.ts +1 -2
- package/dist/components/assistant/xertica-assistant/xertica-assistant.d.ts +2 -96
- package/dist/components/hooks/index.d.ts +3 -0
- package/dist/components/hooks/use-layout-shortcuts.d.ts +22 -0
- package/dist/components/media/audio-player/AudioPlayer.d.ts +4 -1
- package/dist/components/media/audio-player/use-audio-player.d.ts +72 -0
- package/dist/components/shared/CustomTooltipContent.d.ts +20 -0
- package/dist/components/ui/alert/alert.d.ts +1 -1
- package/dist/components/ui/badge/badge.d.ts +1 -1
- package/dist/components/ui/button/button.d.ts +2 -2
- package/dist/contexts/AssistenteContext.d.ts +10 -49
- 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/hooks.cjs.js +30 -10
- package/dist/hooks.es.js +25 -4
- package/dist/index-CkTUgOwX.js +8 -0
- package/dist/{index-COtD8bRW.cjs → index-D3RLKRAs.cjs} +1 -1
- package/dist/index.cjs.js +11 -11
- package/dist/index.es.js +11 -11
- package/dist/index.umd.js +454 -1027
- package/dist/layout.cjs.js +3 -10
- package/dist/layout.es.js +3 -10
- package/dist/media.cjs.js +1 -1
- package/dist/media.es.js +1 -1
- package/dist/pages.cjs.js +1 -1
- package/dist/pages.es.js +1 -1
- package/dist/{sidebar-CK_0ZQHj.cjs → sidebar-CVUGHOS_.cjs} +10 -57
- package/dist/{sidebar-CUuOvYhK.js → sidebar-CmvwjnVb.js} +10 -40
- package/dist/ui.cjs.js +4 -4
- package/dist/ui.es.js +4 -4
- package/dist/use-audio-player-Bkh23vQ3.js +177 -0
- package/dist/use-audio-player-Dn1NR9xN.cjs +176 -0
- package/dist/utils/color-utils.d.ts +51 -0
- package/dist/{xertica-assistant-dyP7KHM5.cjs → xertica-assistant-B1IaHXnB.cjs} +388 -529
- package/dist/xertica-assistant-BMqdyRVi.js +2082 -0
- package/dist/xertica-assistant-Bj3vBCq_.cjs +2081 -0
- package/dist/{xertica-assistant-yX1CFBBo.js → xertica-assistant-DPsESB6t.js} +390 -531
- package/dist/{CodeBlock-BgfYL_rD.cjs → xertica-assistant-Qp3ydksa.cjs} +51 -263
- package/dist/{CodeBlock-DnYNI8rQ.js → xertica-assistant-gnCJdcZY.js} +7 -219
- package/dist/xertica-ui.css +2 -2
- package/docs/architecture-improvements.md +463 -0
- package/docs/architecture.md +1 -1
- package/docs/components/assistant-chart.md +1 -1
- package/docs/components/audio-player.md +46 -0
- package/docs/components/branding.md +251 -0
- package/docs/components/calendar.md +154 -154
- package/docs/components/card-patterns.md +337 -337
- package/docs/components/card.md +235 -235
- package/docs/components/code-block.md +108 -0
- package/docs/components/formatted-document.md +113 -0
- package/docs/components/hooks.md +430 -0
- package/docs/components/image-with-fallback.md +106 -0
- package/docs/components/map-layers.md +140 -0
- package/docs/components/map.md +84 -84
- package/docs/components/modern-chat-input.md +163 -0
- package/docs/components/pages.md +351 -0
- package/docs/components/xertica-provider.md +24 -24
- package/docs/decision-tree.md +287 -287
- package/docs/doc-audit.md +223 -0
- package/docs/getting-started.md +154 -0
- package/docs/llms.md +25 -5
- package/docs/patterns/detail-page.md +276 -0
- package/docs/patterns/settings.md +346 -0
- package/docs/patterns/wizard.md +217 -0
- package/guidelines/Guidelines.md +252 -252
- package/hooks/useTheme.ts +3 -3
- package/imports/Podcast.tsx +388 -388
- package/imports/XerticaAi.tsx +45 -45
- package/imports/XerticaX.tsx +19 -19
- package/imports/svg-aueiaqngck.ts +11 -11
- package/imports/svg-v9krss1ozd.ts +16 -16
- package/imports/svg-vhrdofe3qe.ts +5 -5
- package/llms-compact.txt +327 -327
- package/llms.txt +160 -160
- package/package.json +203 -203
- package/styles/xertica/app-overrides/chat.css +61 -61
- package/styles/xertica/app-overrides/scrollbar.css +33 -33
- package/styles/xertica/integrations/google-maps.css +76 -76
- package/styles/xertica/integrations/sonner.css +73 -73
- package/templates/CLAUDE.md +182 -182
- package/templates/guidelines/Guidelines.md +325 -325
- package/templates/package.json +2 -2
- package/templates/src/features/auth/index.ts +4 -4
- package/templates/src/features/auth/ui/AuthPageShell.tsx +34 -34
- package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -70
- package/templates/src/features/auth/ui/LoginContent.tsx +90 -90
- package/templates/src/features/auth/ui/ResetPasswordContent.tsx +151 -151
- package/templates/src/features/auth/ui/SocialLoginButtons.tsx +59 -59
- package/templates/src/features/auth/ui/VerifyEmailContent.tsx +82 -82
- package/templates/src/features/home/index.ts +1 -1
- package/templates/src/features/home/ui/HomeContent.tsx +100 -100
- package/templates/src/features/template/index.ts +5 -5
- package/templates/src/features/template/ui/CrudTemplate.tsx +3 -3
- package/templates/src/features/template/ui/DashboardTemplate.tsx +3 -3
- package/templates/src/features/template/ui/FormTemplate.tsx +120 -120
- package/templates/src/features/template/ui/LoginTemplate.tsx +3 -3
- package/templates/src/pages/AssistantPage.tsx +328 -328
- package/templates/src/pages/ForgotPasswordPage.tsx +6 -6
- package/templates/src/pages/HomePage.tsx +57 -57
- package/templates/src/pages/LoginPage.tsx +10 -10
- package/templates/src/pages/ResetPasswordPage.tsx +6 -6
- package/templates/src/pages/TemplatePage.tsx +30 -30
- package/templates/src/pages/VerifyEmailPage.tsx +6 -6
- package/templates/src/shared/config/navigation.ts +20 -20
- package/templates/src/shared/lib/auth.ts +20 -20
- package/templates/src/shared/types/auth.ts +3 -3
- package/templates/tsconfig.json +5 -5
- package/utils/color-utils.ts +72 -0
- package/utils/gemini.ts +140 -140
- package/dist/AudioPlayer-B1lt5cPl.cjs +0 -989
- package/dist/AudioPlayer-BZ7bibzU.cjs +0 -982
- package/dist/AudioPlayer-DMcG_c7L.js +0 -990
- package/dist/AudioPlayer-e8LfNoqO.js +0 -983
- package/dist/CodeBlock-7TTgmdGG.cjs +0 -2094
- package/dist/CodeBlock-BeSt1h5P.js +0 -2078
- 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-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/ImageWithFallback-CGtidP6B.cjs +0 -4542
- package/dist/ImageWithFallback-lsg3pdFg.js +0 -4508
- 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-hSwhNQex.js +0 -39
- package/dist/breadcrumb-CqJ7bHY5.js +0 -161
- package/dist/breadcrumb-m9Hb2_XN.cjs +0 -177
- 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/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-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-DW5tYe26.js +0 -8
- package/dist/input-2R4loU86.js +0 -127
- package/dist/input-DWANSKGb.cjs +0 -145
- package/dist/rich-text-editor-0mraWT5y.cjs +0 -2376
- 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-CPV1lEPH.cjs +0 -1748
- 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-skplNlBM.cjs +0 -2345
- package/dist/select-Bkbr0f-Z.cjs +0 -162
- package/dist/select-CvIVdX2n.js +0 -145
- 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-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-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-DMOvImGQ.cjs +0 -4542
- 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-ncXBeE2z.cjs +0 -4235
- 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,243 +1,59 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { type MockResponse } from '../../shared/assistant-utils';
|
|
3
2
|
import { useAssistant } from './use-assistant';
|
|
4
3
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
5
|
-
import {
|
|
6
|
-
MessageSquare,
|
|
7
|
-
Heart,
|
|
8
|
-
History,
|
|
9
|
-
MoreHorizontal,
|
|
10
|
-
X,
|
|
11
|
-
ChevronLeft,
|
|
12
|
-
ChevronRight,
|
|
13
|
-
PanelRight,
|
|
14
|
-
Plus,
|
|
15
|
-
Copy,
|
|
16
|
-
Check,
|
|
17
|
-
FileText,
|
|
18
|
-
Music,
|
|
19
|
-
Image as ImageIcon,
|
|
20
|
-
Radio,
|
|
21
|
-
Loader2,
|
|
22
|
-
Edit,
|
|
23
|
-
Download,
|
|
24
|
-
Search,
|
|
25
|
-
Folder,
|
|
26
|
-
Users,
|
|
27
|
-
ExternalLink,
|
|
28
|
-
Star,
|
|
29
|
-
Clock,
|
|
30
|
-
FolderOpen,
|
|
31
|
-
Filter,
|
|
32
|
-
Mail,
|
|
33
|
-
BarChart3,
|
|
34
|
-
Bookmark,
|
|
35
|
-
Maximize2,
|
|
36
|
-
AlertCircle,
|
|
37
|
-
ThumbsUp,
|
|
38
|
-
ThumbsDown,
|
|
39
|
-
Table as TableIcon,
|
|
40
|
-
ArrowLeft,
|
|
41
|
-
Bold,
|
|
42
|
-
Italic,
|
|
43
|
-
Underline,
|
|
44
|
-
AlignLeft,
|
|
45
|
-
AlignCenter,
|
|
46
|
-
AlignRight,
|
|
47
|
-
List,
|
|
48
|
-
Type
|
|
49
|
-
} from 'lucide-react';
|
|
50
|
-
import {
|
|
51
|
-
Bar,
|
|
52
|
-
BarChart,
|
|
53
|
-
CartesianGrid,
|
|
54
|
-
XAxis,
|
|
55
|
-
Tooltip as RechartsTooltip,
|
|
56
|
-
ResponsiveContainer
|
|
57
|
-
} from "recharts";
|
|
58
|
-
import {
|
|
59
|
-
ChartConfig,
|
|
60
|
-
ChartContainer,
|
|
61
|
-
ChartTooltip,
|
|
62
|
-
ChartTooltipContent,
|
|
63
|
-
ChartLegend,
|
|
64
|
-
ChartLegendContent
|
|
65
|
-
} from '../../ui/chart';
|
|
66
|
-
import {
|
|
67
|
-
Table,
|
|
68
|
-
TableBody,
|
|
69
|
-
TableCaption,
|
|
70
|
-
TableCell,
|
|
71
|
-
TableHead,
|
|
72
|
-
TableHeader,
|
|
73
|
-
TableRow,
|
|
74
|
-
} from '../../ui/table';
|
|
75
|
-
import {
|
|
76
|
-
Dialog,
|
|
77
|
-
DialogContent,
|
|
78
|
-
DialogDescription,
|
|
79
|
-
DialogFooter,
|
|
80
|
-
DialogHeader,
|
|
81
|
-
DialogTitle,
|
|
82
|
-
} from '../../ui/dialog';
|
|
83
|
-
import {
|
|
84
|
-
DropdownMenu,
|
|
85
|
-
DropdownMenuContent,
|
|
86
|
-
DropdownMenuItem,
|
|
87
|
-
DropdownMenuTrigger,
|
|
88
|
-
} from '../../ui/dropdown-menu';
|
|
89
|
-
import { Textarea } from '../../ui/textarea';
|
|
90
|
-
import { Button } from '../../ui/button';
|
|
91
4
|
import { ScrollArea } from '../../ui/scroll-area';
|
|
92
|
-
import { Separator } from '../../ui/separator';
|
|
93
|
-
import { RichTextEditor } from '../../ui/rich-text-editor';
|
|
94
|
-
import { MarkdownMessage } from '../markdown-message';
|
|
95
|
-
import { FormattedDocument } from '../formatted-document';
|
|
96
5
|
import { ModernChatInput } from '../modern-chat-input';
|
|
97
|
-
import type { ActionType } from '../modern-chat-input';
|
|
98
6
|
import { XerticaOrbe } from '../../brand/xertica-orbe';
|
|
99
|
-
import {
|
|
100
|
-
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
7
|
+
import { Button } from '../../ui/button';
|
|
101
8
|
import { cn } from '../../shared/utils';
|
|
102
|
-
import { toast } from 'sonner';
|
|
103
9
|
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
"bg-popover text-popover-foreground shadow-lg animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
|
|
118
|
-
className,
|
|
119
|
-
)}
|
|
120
|
-
{...props}
|
|
121
|
-
>
|
|
122
|
-
{children}
|
|
123
|
-
<TooltipPrimitive.Arrow
|
|
124
|
-
className="fill-popover z-50 drop-shadow-sm"
|
|
125
|
-
width={8}
|
|
126
|
-
height={4}
|
|
127
|
-
/>
|
|
128
|
-
</TooltipPrimitive.Content>
|
|
129
|
-
</TooltipPrimitive.Portal>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
10
|
+
// Sub-components
|
|
11
|
+
import {
|
|
12
|
+
AssistantCollapsedView,
|
|
13
|
+
AssistantHeader,
|
|
14
|
+
AssistantTabBar,
|
|
15
|
+
AssistantWelcomeScreen,
|
|
16
|
+
AssistantMessageBubble,
|
|
17
|
+
AssistantTypingIndicator,
|
|
18
|
+
AssistantConversationList,
|
|
19
|
+
AssistantFeedbackDialog,
|
|
20
|
+
AssistantDocumentEditor,
|
|
21
|
+
} from './parts';
|
|
22
|
+
import type { EvaluationState } from './parts';
|
|
132
23
|
|
|
133
24
|
// ============================================================================
|
|
134
|
-
// TypeScript Interfaces & Types
|
|
25
|
+
// TypeScript Interfaces & Types — imported from shared types.ts and re-exported
|
|
26
|
+
// for backward compatibility with consumers that import from xertica-assistant.
|
|
135
27
|
// ============================================================================
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Metadata about a search source (e.g., a document repository or knowledge base)
|
|
167
|
-
*/
|
|
168
|
-
export interface SearchSource {
|
|
169
|
-
name: string;
|
|
170
|
-
count: number;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* A quick-action command shown below a search result message
|
|
175
|
-
*/
|
|
176
|
-
export interface SearchCommand {
|
|
177
|
-
id: string;
|
|
178
|
-
icon: string;
|
|
179
|
-
label: string;
|
|
180
|
-
description: string;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* A single chat message in the assistant conversation
|
|
185
|
-
*/
|
|
186
|
-
export interface Message {
|
|
187
|
-
id: string;
|
|
188
|
-
type: MessageType;
|
|
189
|
-
content: string;
|
|
190
|
-
timestamp: Date;
|
|
191
|
-
isFavorite?: boolean;
|
|
192
|
-
attachmentType?: AttachmentType;
|
|
193
|
-
attachmentName?: string;
|
|
194
|
-
documentContent?: string;
|
|
195
|
-
documentTitle?: string;
|
|
196
|
-
audioUrl?: string;
|
|
197
|
-
searchResults?: SearchResult[];
|
|
198
|
-
searchSources?: SearchSource[];
|
|
199
|
-
searchCommands?: SearchCommand[];
|
|
200
|
-
chartData?: any[];
|
|
201
|
-
chartConfig?: any;
|
|
202
|
-
tableData?: {
|
|
203
|
-
caption?: string;
|
|
204
|
-
headers: string[];
|
|
205
|
-
rows: (string | React.ReactNode)[][];
|
|
206
|
-
};
|
|
207
|
-
evaluation?: 'like' | 'dislike';
|
|
208
|
-
evaluationReason?: string;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* A saved conversation entry shown in the history panel
|
|
213
|
-
*/
|
|
214
|
-
export interface Conversation {
|
|
215
|
-
id: string;
|
|
216
|
-
title: string;
|
|
217
|
-
lastMessage?: string;
|
|
218
|
-
timestamp: string;
|
|
219
|
-
isFavorite: boolean;
|
|
220
|
-
messages: Message[];
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* A suggested prompt shown to the user in the chat input area
|
|
225
|
-
*/
|
|
226
|
-
export interface Suggestion {
|
|
227
|
-
id: string;
|
|
228
|
-
text: string;
|
|
229
|
-
icon?: React.ReactNode;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Layout mode for the assistant panel
|
|
234
|
-
*/
|
|
235
|
-
export type AssistantMode = 'collapsed' | 'expanded' | 'fullPage';
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Available tabs in the assistant panel
|
|
239
|
-
*/
|
|
240
|
-
export type AssistantTab = 'chat' | 'historico' | 'favoritos';
|
|
28
|
+
import type {
|
|
29
|
+
MessageType,
|
|
30
|
+
AttachmentType,
|
|
31
|
+
SearchResultType,
|
|
32
|
+
AssistantMode,
|
|
33
|
+
AssistantTab,
|
|
34
|
+
SearchResult,
|
|
35
|
+
SearchSource,
|
|
36
|
+
SearchCommand,
|
|
37
|
+
Message,
|
|
38
|
+
Conversation,
|
|
39
|
+
Suggestion,
|
|
40
|
+
MockResponse,
|
|
41
|
+
} from './types';
|
|
42
|
+
|
|
43
|
+
export type {
|
|
44
|
+
MessageType,
|
|
45
|
+
AttachmentType,
|
|
46
|
+
SearchResultType,
|
|
47
|
+
AssistantMode,
|
|
48
|
+
AssistantTab,
|
|
49
|
+
SearchResult,
|
|
50
|
+
SearchSource,
|
|
51
|
+
SearchCommand,
|
|
52
|
+
Message,
|
|
53
|
+
Conversation,
|
|
54
|
+
Suggestion,
|
|
55
|
+
MockResponse,
|
|
56
|
+
};
|
|
241
57
|
|
|
242
58
|
// ============================================================================
|
|
243
59
|
// Component Props
|
|
@@ -277,8 +93,6 @@ export interface XerticaAssistantProps {
|
|
|
277
93
|
*/
|
|
278
94
|
customResponses?: MockResponse[];
|
|
279
95
|
|
|
280
|
-
|
|
281
|
-
|
|
282
96
|
/**
|
|
283
97
|
* Callback fired when the user navigates to the settings page
|
|
284
98
|
*/
|
|
@@ -510,10 +324,8 @@ export function XerticaAssistant({
|
|
|
510
324
|
abaSelecionada,
|
|
511
325
|
setAbaSelecionada,
|
|
512
326
|
mensagens,
|
|
513
|
-
setMensagens,
|
|
514
327
|
mensagem,
|
|
515
328
|
setMensagem,
|
|
516
|
-
conversas,
|
|
517
329
|
conversaAtual,
|
|
518
330
|
conversasFiltradas,
|
|
519
331
|
copiedId,
|
|
@@ -574,11 +386,12 @@ export function XerticaAssistant({
|
|
|
574
386
|
isFullPage
|
|
575
387
|
? '100%'
|
|
576
388
|
: isExpanded
|
|
577
|
-
?
|
|
389
|
+
? '420px'
|
|
578
390
|
: '80px' // Compacto quando fechado - apenas ícones
|
|
579
391
|
);
|
|
580
392
|
const containerHeight = height ?? 'h-full';
|
|
581
393
|
|
|
394
|
+
// Mobile floating button — shown when collapsed on mobile
|
|
582
395
|
if (isMobile && !isExpanded) {
|
|
583
396
|
return (
|
|
584
397
|
<Button
|
|
@@ -638,193 +451,35 @@ export function XerticaAssistant({
|
|
|
638
451
|
>
|
|
639
452
|
{/* Document Editor Overlay */}
|
|
640
453
|
{editingDocument && !isFullPage && (
|
|
641
|
-
<
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
)}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
<div className="h-full flex flex-col">
|
|
649
|
-
{/* Header Toolbar */}
|
|
650
|
-
<div className="px-4 h-[64px] border-b border-border bg-card flex items-center justify-between">
|
|
651
|
-
<div className="flex items-center gap-3">
|
|
652
|
-
<div className="p-2 bg-primary/10 rounded-md">
|
|
653
|
-
<FileText className="w-4 h-4 text-primary" />
|
|
654
|
-
</div>
|
|
655
|
-
<h3 className="font-semibold text-card-foreground text-sm">{editingDocument.title}</h3>
|
|
656
|
-
</div>
|
|
657
|
-
<Button
|
|
658
|
-
variant="ghost"
|
|
659
|
-
size="icon"
|
|
660
|
-
className="h-8 w-8 rounded-full"
|
|
661
|
-
onClick={() => setEditingDocument(null)}
|
|
662
|
-
aria-label="Fechar editor de documento"
|
|
663
|
-
>
|
|
664
|
-
<X className="w-4 h-4" />
|
|
665
|
-
</Button>
|
|
666
|
-
</div>
|
|
667
|
-
|
|
668
|
-
{/* Rich Text Editor */}
|
|
669
|
-
<div className="flex-1 bg-muted/20 p-0 sm:p-6 overflow-hidden">
|
|
670
|
-
<RichTextEditor
|
|
671
|
-
value={editingDocument.content || ''}
|
|
672
|
-
onChange={(newVal) => setEditingDocument(editingDocument ? { ...editingDocument, content: newVal } : null)}
|
|
673
|
-
placeholder="Comece a digitar o conteúdo do seu documento aqui..."
|
|
674
|
-
className="max-w-4xl mx-auto h-full"
|
|
675
|
-
actionButton={
|
|
676
|
-
<Button size="sm" className="gap-2 h-8">
|
|
677
|
-
<Check className="w-3.5 h-3.5" />
|
|
678
|
-
Salvar
|
|
679
|
-
</Button>
|
|
680
|
-
}
|
|
681
|
-
/>
|
|
682
|
-
</div>
|
|
683
|
-
</div>
|
|
684
|
-
</div>
|
|
454
|
+
<AssistantDocumentEditor
|
|
455
|
+
document={editingDocument}
|
|
456
|
+
isMobile={isMobile}
|
|
457
|
+
containerWidth={containerWidth}
|
|
458
|
+
onClose={() => setEditingDocument(null)}
|
|
459
|
+
onChange={(doc) => setEditingDocument(doc)}
|
|
460
|
+
/>
|
|
685
461
|
)}
|
|
686
|
-
{/* Header - Toggle Button - Apenas visível quando não está em fullPage */}
|
|
687
|
-
{!isFullPage && (
|
|
688
|
-
<div
|
|
689
|
-
className={cn(
|
|
690
|
-
"border-b border-border flex items-center h-[64px]",
|
|
691
|
-
isExpanded ? "justify-between px-4" : "justify-center px-0"
|
|
692
|
-
)}
|
|
693
|
-
>
|
|
694
|
-
{isExpanded && (
|
|
695
|
-
<motion.div
|
|
696
|
-
initial={{ opacity: 0, x: -10 }}
|
|
697
|
-
animate={{ opacity: 1, x: 0 }}
|
|
698
|
-
exit={{ opacity: 0, x: -10 }}
|
|
699
|
-
className="flex items-center gap-2 overflow-hidden"
|
|
700
|
-
>
|
|
701
|
-
<div className="flex-shrink-0">
|
|
702
|
-
<XerticaOrbe size={32} />
|
|
703
|
-
</div>
|
|
704
|
-
<span className="text-foreground font-medium truncate">Assistente Xertica</span>
|
|
705
|
-
</motion.div>
|
|
706
|
-
)}
|
|
707
462
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
title="Expandir assistente"
|
|
716
|
-
aria-label="Expandir assistente"
|
|
717
|
-
>
|
|
718
|
-
<Maximize2 className="w-4 h-4" />
|
|
719
|
-
</Button>
|
|
720
|
-
)}
|
|
721
|
-
|
|
722
|
-
<Button
|
|
723
|
-
variant="ghost"
|
|
724
|
-
size="sm"
|
|
725
|
-
onClick={handleToggle}
|
|
726
|
-
className={cn(
|
|
727
|
-
"h-8 w-8 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-full",
|
|
728
|
-
!isExpanded && "w-10 h-10" // Slightly larger touch target when collapsed if desired, or keep consistent
|
|
729
|
-
)}
|
|
730
|
-
aria-label={isExpanded ? "Recolher assistente" : "Expandir assistente"}
|
|
731
|
-
>
|
|
732
|
-
{isExpanded ? (
|
|
733
|
-
<ChevronRight className="w-4 h-4" />
|
|
734
|
-
) : (
|
|
735
|
-
<PanelRight className="w-4 h-4" />
|
|
736
|
-
)}
|
|
737
|
-
</Button>
|
|
738
|
-
</div>
|
|
739
|
-
</div>
|
|
463
|
+
{/* Header — only visible when not in fullPage mode */}
|
|
464
|
+
{!isFullPage && (
|
|
465
|
+
<AssistantHeader
|
|
466
|
+
isExpanded={isExpanded}
|
|
467
|
+
onToggle={handleToggle}
|
|
468
|
+
onNavigateFullPage={onNavigateFullPage}
|
|
469
|
+
/>
|
|
740
470
|
)}
|
|
741
471
|
|
|
742
|
-
{/* Collapsed State
|
|
472
|
+
{/* Collapsed State — Icons Only */}
|
|
743
473
|
{!isExpanded && !isFullPage && (
|
|
744
|
-
<
|
|
745
|
-
{
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
className="w-10 h-10 rounded-full flex items-center justify-center hover:bg-accent/50 transition-colors duration-200 cursor-pointer mx-auto"
|
|
751
|
-
aria-label="Abrir assistente"
|
|
752
|
-
>
|
|
753
|
-
<XerticaOrbe size={32} />
|
|
754
|
-
</button>
|
|
755
|
-
</TooltipTrigger>
|
|
756
|
-
<AssistantTooltipContent
|
|
757
|
-
side="left"
|
|
758
|
-
sideOffset={8}
|
|
759
|
-
>
|
|
760
|
-
<p>Assistente Xertica</p>
|
|
761
|
-
</AssistantTooltipContent>
|
|
762
|
-
</Tooltip>
|
|
763
|
-
|
|
764
|
-
<Tooltip>
|
|
765
|
-
<TooltipTrigger asChild>
|
|
766
|
-
<Button
|
|
767
|
-
variant="ghost"
|
|
768
|
-
size="sm"
|
|
769
|
-
onClick={() => handleExpandWithTab('chat')}
|
|
770
|
-
className="w-8 h-8 p-0 text-muted-foreground"
|
|
771
|
-
>
|
|
772
|
-
<MessageSquare className="w-4 h-4" />
|
|
773
|
-
</Button>
|
|
774
|
-
</TooltipTrigger>
|
|
775
|
-
<AssistantTooltipContent
|
|
776
|
-
side="left"
|
|
777
|
-
sideOffset={8}
|
|
778
|
-
>
|
|
779
|
-
<p>Chat</p>
|
|
780
|
-
</AssistantTooltipContent>
|
|
781
|
-
</Tooltip>
|
|
782
|
-
|
|
783
|
-
{showFavorites && (
|
|
784
|
-
<Tooltip>
|
|
785
|
-
<TooltipTrigger asChild>
|
|
786
|
-
<Button
|
|
787
|
-
variant="ghost"
|
|
788
|
-
size="sm"
|
|
789
|
-
onClick={() => handleExpandWithTab('favoritos')}
|
|
790
|
-
className="w-8 h-8 p-0 text-muted-foreground"
|
|
791
|
-
>
|
|
792
|
-
<Heart className="w-4 h-4" />
|
|
793
|
-
</Button>
|
|
794
|
-
</TooltipTrigger>
|
|
795
|
-
<AssistantTooltipContent
|
|
796
|
-
side="left"
|
|
797
|
-
sideOffset={8}
|
|
798
|
-
>
|
|
799
|
-
<p>Favoritos</p>
|
|
800
|
-
</AssistantTooltipContent>
|
|
801
|
-
</Tooltip>
|
|
802
|
-
)}
|
|
803
|
-
|
|
804
|
-
{showHistory && (
|
|
805
|
-
<Tooltip>
|
|
806
|
-
<TooltipTrigger asChild>
|
|
807
|
-
<Button
|
|
808
|
-
variant="ghost"
|
|
809
|
-
size="sm"
|
|
810
|
-
onClick={() => handleExpandWithTab('historico')}
|
|
811
|
-
className="w-8 h-8 p-0 text-muted-foreground"
|
|
812
|
-
>
|
|
813
|
-
<History className="w-4 h-4" />
|
|
814
|
-
</Button>
|
|
815
|
-
</TooltipTrigger>
|
|
816
|
-
<AssistantTooltipContent
|
|
817
|
-
side="left"
|
|
818
|
-
sideOffset={8}
|
|
819
|
-
>
|
|
820
|
-
<p>Histórico</p>
|
|
821
|
-
</AssistantTooltipContent>
|
|
822
|
-
</Tooltip>
|
|
823
|
-
)}
|
|
824
|
-
</div>
|
|
474
|
+
<AssistantCollapsedView
|
|
475
|
+
showHistory={showHistory}
|
|
476
|
+
showFavorites={showFavorites}
|
|
477
|
+
onToggle={handleToggle}
|
|
478
|
+
onExpandWithTab={handleExpandWithTab}
|
|
479
|
+
/>
|
|
825
480
|
)}
|
|
826
481
|
|
|
827
|
-
{/* Expanded State
|
|
482
|
+
{/* Expanded State — Full Content */}
|
|
828
483
|
<AnimatePresence>
|
|
829
484
|
{(isExpanded || isFullPage) && (
|
|
830
485
|
<motion.div
|
|
@@ -834,600 +489,61 @@ export function XerticaAssistant({
|
|
|
834
489
|
transition={{ duration: 0.2 }}
|
|
835
490
|
className="flex-1 flex flex-col overflow-hidden"
|
|
836
491
|
>
|
|
837
|
-
{/* Navigation Tabs
|
|
492
|
+
{/* Navigation Tabs — hidden in fullPage mode and when no secondary tabs are enabled */}
|
|
838
493
|
{!isFullPage && (showHistory || showFavorites) && (
|
|
839
|
-
<
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
size="sm"
|
|
846
|
-
onClick={() => setAbaSelecionada('chat')}
|
|
847
|
-
className="flex-1 h-8"
|
|
848
|
-
aria-label="Ver chat"
|
|
849
|
-
>
|
|
850
|
-
<MessageSquare className="w-3 h-3 mr-1" />
|
|
851
|
-
Chat
|
|
852
|
-
</Button>
|
|
853
|
-
{showHistory && (
|
|
854
|
-
<Button
|
|
855
|
-
variant={abaSelecionada === 'historico' ? 'default' : 'ghost'}
|
|
856
|
-
size="sm"
|
|
857
|
-
onClick={() => setAbaSelecionada('historico')}
|
|
858
|
-
className="flex-1 h-8"
|
|
859
|
-
aria-label="Ver histórico de conversas"
|
|
860
|
-
>
|
|
861
|
-
<History className="w-3 h-3 mr-1" />
|
|
862
|
-
Histórico
|
|
863
|
-
</Button>
|
|
864
|
-
)}
|
|
865
|
-
{showFavorites && (
|
|
866
|
-
<Button
|
|
867
|
-
variant={abaSelecionada === 'favoritos' ? 'default' : 'ghost'}
|
|
868
|
-
size="sm"
|
|
869
|
-
onClick={() => setAbaSelecionada('favoritos')}
|
|
870
|
-
className="flex-1 h-8"
|
|
871
|
-
aria-label="Ver mensagens favoritas"
|
|
872
|
-
>
|
|
873
|
-
<Heart className="w-3 h-3 mr-1" />
|
|
874
|
-
Favoritos
|
|
875
|
-
</Button>
|
|
876
|
-
)}
|
|
877
|
-
</div>
|
|
878
|
-
</div>
|
|
494
|
+
<AssistantTabBar
|
|
495
|
+
activeTab={abaSelecionada}
|
|
496
|
+
showHistory={showHistory}
|
|
497
|
+
showFavorites={showFavorites}
|
|
498
|
+
onTabChange={setAbaSelecionada}
|
|
499
|
+
/>
|
|
879
500
|
)}
|
|
880
501
|
|
|
881
502
|
{/* Content Area */}
|
|
882
503
|
<div className="flex-1 overflow-hidden flex flex-col">
|
|
504
|
+
|
|
505
|
+
{/* Chat Tab */}
|
|
883
506
|
{abaSelecionada === 'chat' && (
|
|
884
507
|
<div className={`flex-1 flex flex-col min-h-0 ${isFullPage ? 'mx-auto w-full max-w-6xl' : ''}`}>
|
|
885
|
-
{/* API Key Warning Banner */}
|
|
886
|
-
|
|
887
|
-
|
|
888
508
|
{mensagens.length === 0 ? (
|
|
889
|
-
<
|
|
890
|
-
{
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
{welcomeMessage}
|
|
900
|
-
</p>
|
|
901
|
-
</div>
|
|
902
|
-
|
|
903
|
-
{/* Suggestions */}
|
|
904
|
-
{(sugestoes.length > 0 || richSuggestions.length > 0) && (
|
|
905
|
-
<div className="px-4 pb-4 space-y-2">
|
|
906
|
-
{sugestoes.map((sugestao) => (
|
|
907
|
-
<button
|
|
908
|
-
key={sugestao.id}
|
|
909
|
-
onClick={() => handleEnviarMensagem(sugestao.text)}
|
|
910
|
-
className="w-full p-3 text-left rounded-[var(--radius-card)] bg-muted text-foreground transition-colors duration-200 hover:bg-muted/80"
|
|
911
|
-
>
|
|
912
|
-
{sugestao.text}
|
|
913
|
-
</button>
|
|
914
|
-
))}
|
|
915
|
-
|
|
916
|
-
{richSuggestions.length > 0 && (
|
|
917
|
-
!showMoreSuggestions ? (
|
|
918
|
-
<Button
|
|
919
|
-
variant="ghost"
|
|
920
|
-
size="sm"
|
|
921
|
-
onClick={() => setShowMoreSuggestions(true)}
|
|
922
|
-
className="w-full justify-start text-muted-foreground"
|
|
923
|
-
>
|
|
924
|
-
<MoreHorizontal className="w-4 h-4 mr-2" />
|
|
925
|
-
Mais sugestões
|
|
926
|
-
</Button>
|
|
927
|
-
) : (
|
|
928
|
-
<div className="space-y-2 pt-2 border-t border-border mt-2 animate-in slide-in-from-top-2">
|
|
929
|
-
{richSuggestions.map((sugestao) => (
|
|
930
|
-
<button
|
|
931
|
-
key={sugestao.id}
|
|
932
|
-
onClick={() => handleRichSuggestionClick(sugestao)}
|
|
933
|
-
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"
|
|
934
|
-
>
|
|
935
|
-
<div className="flex items-center gap-2">
|
|
936
|
-
{sugestao.id.includes('chart') && <BarChart3 className="w-4 h-4 text-primary" />}
|
|
937
|
-
{sugestao.id.includes('table') && <TableIcon className="w-4 h-4 text-primary" />}
|
|
938
|
-
<span className="font-medium">{sugestao.text}</span>
|
|
939
|
-
</div>
|
|
940
|
-
</button>
|
|
941
|
-
))}
|
|
942
|
-
<Button
|
|
943
|
-
variant="ghost"
|
|
944
|
-
size="sm"
|
|
945
|
-
onClick={() => setShowMoreSuggestions(false)}
|
|
946
|
-
className="w-full justify-center text-muted-foreground mt-2"
|
|
947
|
-
>
|
|
948
|
-
<ChevronLeft className="w-4 h-4 mr-2" />
|
|
949
|
-
Voltar
|
|
950
|
-
</Button>
|
|
951
|
-
</div>
|
|
952
|
-
)
|
|
953
|
-
)}
|
|
954
|
-
</div>
|
|
955
|
-
)}
|
|
956
|
-
</div>
|
|
509
|
+
<AssistantWelcomeScreen
|
|
510
|
+
userName={userName}
|
|
511
|
+
welcomeMessage={welcomeMessage}
|
|
512
|
+
suggestions={sugestoes}
|
|
513
|
+
richSuggestions={richSuggestions}
|
|
514
|
+
showMoreSuggestions={showMoreSuggestions}
|
|
515
|
+
onSetShowMoreSuggestions={setShowMoreSuggestions}
|
|
516
|
+
onSendSuggestion={handleEnviarMensagem}
|
|
517
|
+
onRichSuggestionClick={handleRichSuggestionClick}
|
|
518
|
+
/>
|
|
957
519
|
) : (
|
|
958
520
|
<ScrollArea className="flex-1 min-h-0 overflow-x-hidden [&_[data-radix-scroll-area-viewport]>div]:!block">
|
|
959
521
|
<div className="space-y-4 px-4 py-4 max-w-6xl mx-auto !block !w-full">
|
|
960
522
|
{mensagens.map((msg) => (
|
|
961
|
-
<
|
|
523
|
+
<AssistantMessageBubble
|
|
962
524
|
key={msg.id}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
{
|
|
968
|
-
{
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
? "w-full max-w-full"
|
|
982
|
-
: "w-fit max-w-[95%] md:max-w-[90%]"
|
|
983
|
-
)
|
|
984
|
-
)}>
|
|
985
|
-
<div
|
|
986
|
-
className={cn(
|
|
987
|
-
"px-4 py-2 break-words overflow-hidden overflow-x-hidden w-full min-w-0 rounded-2xl",
|
|
988
|
-
msg.type === 'user'
|
|
989
|
-
? "bg-primary text-primary-foreground shadow-sm"
|
|
990
|
-
: "bg-muted text-foreground"
|
|
991
|
-
)}
|
|
992
|
-
>
|
|
993
|
-
{/* Document Header with Edit and Download Buttons */}
|
|
994
|
-
{msg.attachmentType === 'document' && (
|
|
995
|
-
<div
|
|
996
|
-
className="flex items-center justify-between mb-2 pb-2 border-b border-border min-w-0 overflow-hidden"
|
|
997
|
-
>
|
|
998
|
-
<div className="flex items-center gap-2 min-w-0 flex-1 overflow-hidden">
|
|
999
|
-
<FileText className="w-4 h-4 flex-shrink-0" />
|
|
1000
|
-
<span className="text-sm font-medium break-words">{msg.attachmentName}</span>
|
|
1001
|
-
</div>
|
|
1002
|
-
<div className="flex items-center gap-1 flex-shrink-0">
|
|
1003
|
-
<Button
|
|
1004
|
-
variant="ghost"
|
|
1005
|
-
size="sm"
|
|
1006
|
-
onClick={() => msg.documentContent && msg.attachmentName && handleDownloadDocument(msg.documentContent, msg.attachmentName)}
|
|
1007
|
-
className="h-6 px-2"
|
|
1008
|
-
title="Baixar"
|
|
1009
|
-
>
|
|
1010
|
-
<Download className="w-3 h-3" />
|
|
1011
|
-
</Button>
|
|
1012
|
-
<Button
|
|
1013
|
-
variant="ghost"
|
|
1014
|
-
size="sm"
|
|
1015
|
-
onClick={() => msg.documentContent && msg.documentTitle && handleEditDocument(msg.documentContent, msg.documentTitle)}
|
|
1016
|
-
className="h-6 px-2"
|
|
1017
|
-
>
|
|
1018
|
-
<Edit className="w-3 h-3 mr-1" />
|
|
1019
|
-
Editar
|
|
1020
|
-
</Button>
|
|
1021
|
-
</div>
|
|
1022
|
-
</div>
|
|
1023
|
-
)}
|
|
1024
|
-
|
|
1025
|
-
{/* Attachments */}
|
|
1026
|
-
{msg.attachmentType && msg.attachmentType !== 'podcast' && msg.attachmentType !== 'document' && (
|
|
1027
|
-
<div
|
|
1028
|
-
className="flex items-center gap-2 mb-2 pb-2 border-b border-border min-w-0 overflow-hidden"
|
|
1029
|
-
>
|
|
1030
|
-
{msg.attachmentType === 'file' && <FileText className="w-4 h-4 flex-shrink-0" />}
|
|
1031
|
-
{msg.attachmentType === 'audio' && <Music className="w-4 h-4 flex-shrink-0" />}
|
|
1032
|
-
{msg.attachmentType === 'image' && <ImageIcon className="w-4 h-4 flex-shrink-0" />}
|
|
1033
|
-
<span className="text-small break-words">{msg.attachmentName}</span>
|
|
1034
|
-
</div>
|
|
1035
|
-
)}
|
|
1036
|
-
|
|
1037
|
-
{/* Message Content */}
|
|
1038
|
-
{msg.type === 'user' ? (
|
|
1039
|
-
<p className="whitespace-pre-wrap break-words">{msg.content}</p>
|
|
1040
|
-
) : (
|
|
1041
|
-
<>
|
|
1042
|
-
{(msg.content.includes('🔐') || msg.content.includes('❌')) && (
|
|
1043
|
-
<div
|
|
1044
|
-
className="mb-3 p-3 border rounded-[var(--radius)] overflow-hidden bg-[var(--toast-error-bg)]/20 border-[var(--toast-error-border)]/30"
|
|
1045
|
-
>
|
|
1046
|
-
<div className="flex items-start gap-2 min-w-0">
|
|
1047
|
-
<AlertCircle className="w-5 h-5 flex-shrink-0 mt-0.5 text-[var(--toast-error-icon)]" />
|
|
1048
|
-
<div className="flex-1 min-w-0 overflow-hidden">
|
|
1049
|
-
<MarkdownMessage
|
|
1050
|
-
content={msg.content}
|
|
1051
|
-
className="text-foreground"
|
|
1052
|
-
/>
|
|
1053
|
-
</div>
|
|
1054
|
-
</div>
|
|
1055
|
-
</div>
|
|
1056
|
-
)}
|
|
1057
|
-
{!(msg.content.includes('🔐') || msg.content.includes('❌')) && (
|
|
1058
|
-
<MarkdownMessage
|
|
1059
|
-
content={msg.content}
|
|
1060
|
-
className="text-foreground"
|
|
1061
|
-
/>
|
|
1062
|
-
)}
|
|
1063
|
-
</>
|
|
1064
|
-
)}
|
|
1065
|
-
|
|
1066
|
-
{/* Chart Rendering */}
|
|
1067
|
-
{msg.chartData && msg.chartConfig && (
|
|
1068
|
-
<div className="mt-4 w-full h-[300px] min-w-[300px]">
|
|
1069
|
-
<ChartContainer config={msg.chartConfig} className="h-full w-full">
|
|
1070
|
-
<BarChart accessibilityLayer data={msg.chartData}>
|
|
1071
|
-
<CartesianGrid vertical={false} />
|
|
1072
|
-
<XAxis
|
|
1073
|
-
dataKey="month"
|
|
1074
|
-
tickLine={false}
|
|
1075
|
-
tickMargin={10}
|
|
1076
|
-
axisLine={false}
|
|
1077
|
-
tickFormatter={(value) => value.slice(0, 3)}
|
|
1078
|
-
/>
|
|
1079
|
-
<ChartTooltip content={<ChartTooltipContent />} />
|
|
1080
|
-
<ChartLegend content={<ChartLegendContent />} />
|
|
1081
|
-
{Object.keys(msg.chartConfig).map((key) => (
|
|
1082
|
-
<Bar key={key} dataKey={key} fill={`var(--color-${key})`} radius={4} />
|
|
1083
|
-
))}
|
|
1084
|
-
</BarChart>
|
|
1085
|
-
</ChartContainer>
|
|
1086
|
-
</div>
|
|
1087
|
-
)}
|
|
1088
|
-
|
|
1089
|
-
{/* Table Rendering */}
|
|
1090
|
-
{msg.tableData && (
|
|
1091
|
-
<div className="mt-4 w-full max-w-full border rounded-[var(--radius)] overflow-x-auto custom-scrollbar relative">
|
|
1092
|
-
<Table>
|
|
1093
|
-
{msg.tableData.caption && <TableCaption>{msg.tableData.caption}</TableCaption>}
|
|
1094
|
-
<TableHeader>
|
|
1095
|
-
<TableRow>
|
|
1096
|
-
{msg.tableData.headers.map((header, i) => (
|
|
1097
|
-
<TableHead key={i}>{header}</TableHead>
|
|
1098
|
-
))}
|
|
1099
|
-
</TableRow>
|
|
1100
|
-
</TableHeader>
|
|
1101
|
-
<TableBody>
|
|
1102
|
-
{msg.tableData.rows.map((row, i) => (
|
|
1103
|
-
<TableRow key={i}>
|
|
1104
|
-
{row.map((cell, j) => (
|
|
1105
|
-
<TableCell key={j}>{cell}</TableCell>
|
|
1106
|
-
))}
|
|
1107
|
-
</TableRow>
|
|
1108
|
-
))}
|
|
1109
|
-
</TableBody>
|
|
1110
|
-
</Table>
|
|
1111
|
-
</div>
|
|
1112
|
-
)}
|
|
1113
|
-
|
|
1114
|
-
{/* Document Preview */}
|
|
1115
|
-
{msg.attachmentType === 'document' && msg.documentContent && (
|
|
1116
|
-
<div
|
|
1117
|
-
className="mt-3 pt-3 border-t border-border overflow-hidden"
|
|
1118
|
-
>
|
|
1119
|
-
<FormattedDocument
|
|
1120
|
-
content={msg.documentContent}
|
|
1121
|
-
maxPreviewLength={250}
|
|
1122
|
-
/>
|
|
1123
|
-
</div>
|
|
1124
|
-
)}
|
|
1125
|
-
|
|
1126
|
-
{/* Podcast Player */}
|
|
1127
|
-
{msg.attachmentType === 'podcast' && msg.audioUrl && (
|
|
1128
|
-
<div
|
|
1129
|
-
className="mt-3 pt-3 border-t border-border overflow-hidden"
|
|
1130
|
-
>
|
|
1131
|
-
<div className="flex items-center justify-between mb-3 min-w-0 overflow-hidden">
|
|
1132
|
-
<div className="flex items-center gap-2 min-w-0 flex-1 overflow-hidden">
|
|
1133
|
-
<div
|
|
1134
|
-
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)]"
|
|
1135
|
-
>
|
|
1136
|
-
<Radio className="w-3 h-3 text-white" />
|
|
1137
|
-
</div>
|
|
1138
|
-
<span className="text-sm font-medium break-words">
|
|
1139
|
-
{msg.attachmentName}
|
|
1140
|
-
</span>
|
|
1141
|
-
</div>
|
|
1142
|
-
<Button
|
|
1143
|
-
variant="ghost"
|
|
1144
|
-
size="sm"
|
|
1145
|
-
onClick={() => msg.audioUrl && msg.attachmentName && handleDownloadPodcast(msg.audioUrl, msg.attachmentName)}
|
|
1146
|
-
className="h-6 px-2 flex-shrink-0"
|
|
1147
|
-
title="Baixar"
|
|
1148
|
-
>
|
|
1149
|
-
<Download className="w-3 h-3" />
|
|
1150
|
-
</Button>
|
|
1151
|
-
</div>
|
|
1152
|
-
<div
|
|
1153
|
-
className="rounded-[var(--radius)] p-2 overflow-hidden bg-gradient-to-r from-[var(--chart-1)]/10 to-[var(--chart-4)]/10"
|
|
1154
|
-
>
|
|
1155
|
-
<audio
|
|
1156
|
-
controls
|
|
1157
|
-
className="w-full max-w-full h-10 outline-none"
|
|
1158
|
-
>
|
|
1159
|
-
<source src={msg.audioUrl} type="audio/mpeg" />
|
|
1160
|
-
Seu navegador não suporta o elemento de áudio.
|
|
1161
|
-
</audio>
|
|
1162
|
-
</div>
|
|
1163
|
-
</div>
|
|
1164
|
-
)}
|
|
1165
|
-
|
|
1166
|
-
{/* Search Results */}
|
|
1167
|
-
{msg.attachmentType === 'search' && msg.searchResults && (
|
|
1168
|
-
<div
|
|
1169
|
-
className="mt-3 pt-3 border-t border-border space-y-4 overflow-hidden"
|
|
1170
|
-
>
|
|
1171
|
-
<div className="overflow-hidden">
|
|
1172
|
-
<div className="flex items-center gap-2 mb-3">
|
|
1173
|
-
<Search className="w-4 h-4 text-[var(--chart-4)]" />
|
|
1174
|
-
<h4 className="text-foreground">
|
|
1175
|
-
Resultados Encontrados ({msg.searchResults.length})
|
|
1176
|
-
</h4>
|
|
1177
|
-
</div>
|
|
1178
|
-
<div className="space-y-2 overflow-hidden">
|
|
1179
|
-
{msg.searchResults.map((result) => (
|
|
1180
|
-
<div
|
|
1181
|
-
key={result.id}
|
|
1182
|
-
onClick={() => handleOpenSearchResult(result)}
|
|
1183
|
-
className="p-3 rounded-[var(--radius)] border border-border transition-all cursor-pointer group overflow-hidden hover:bg-muted/50"
|
|
1184
|
-
>
|
|
1185
|
-
<div className="flex items-start justify-between gap-2 min-w-0">
|
|
1186
|
-
<div className="flex items-start gap-2 flex-1 min-w-0 overflow-hidden">
|
|
1187
|
-
<div className="mt-0.5 flex-shrink-0">
|
|
1188
|
-
{result.type === 'document' && <FileText className="w-4 h-4 text-[var(--chart-4)]" />}
|
|
1189
|
-
{result.type === 'project' && <FolderOpen className="w-4 h-4 text-[var(--chart-1)]" />}
|
|
1190
|
-
{result.type === 'conversation' && <MessageSquare className="w-4 h-4 text-[var(--chart-2)]" />}
|
|
1191
|
-
{result.type === 'file' && <Folder className="w-4 h-4 text-[var(--chart-3)]" />}
|
|
1192
|
-
{result.type === 'contact' && <Users className="w-4 h-4 text-[var(--chart-5)]" />}
|
|
1193
|
-
</div>
|
|
1194
|
-
<div className="flex-1 min-w-0 overflow-hidden">
|
|
1195
|
-
<div className="flex items-start gap-2 min-w-0">
|
|
1196
|
-
<h5 className="text-sm font-medium break-words flex-1 min-w-0 text-foreground">
|
|
1197
|
-
{result.title}
|
|
1198
|
-
</h5>
|
|
1199
|
-
<span
|
|
1200
|
-
className="px-1.5 py-0.5 rounded-sm flex-shrink-0 self-start bg-[var(--chart-4)]/10 text-[var(--chart-4)]"
|
|
1201
|
-
>
|
|
1202
|
-
{result.relevance}%
|
|
1203
|
-
</span>
|
|
1204
|
-
</div>
|
|
1205
|
-
<p className="text-sm text-muted-foreground mt-1 line-clamp-2 break-words">
|
|
1206
|
-
{result.description}
|
|
1207
|
-
</p>
|
|
1208
|
-
<div className="flex items-center gap-3 mt-2 flex-wrap min-w-0">
|
|
1209
|
-
<span className="text-sm text-muted-foreground flex items-center gap-1 min-w-0 max-w-full">
|
|
1210
|
-
<ExternalLink className="w-3 h-3 flex-shrink-0" />
|
|
1211
|
-
<span className="truncate">{result.path}</span>
|
|
1212
|
-
</span>
|
|
1213
|
-
{result.lastModified && (
|
|
1214
|
-
<span className="text-sm text-muted-foreground flex items-center gap-1 flex-shrink-0">
|
|
1215
|
-
<Clock className="w-3 h-3" />
|
|
1216
|
-
{result.lastModified}
|
|
1217
|
-
</span>
|
|
1218
|
-
)}
|
|
1219
|
-
</div>
|
|
1220
|
-
</div>
|
|
1221
|
-
</div>
|
|
1222
|
-
</div>
|
|
1223
|
-
</div>
|
|
1224
|
-
))}
|
|
1225
|
-
</div>
|
|
1226
|
-
</div>
|
|
1227
|
-
|
|
1228
|
-
{/* Search Sources */}
|
|
1229
|
-
{msg.searchSources && (
|
|
1230
|
-
<div>
|
|
1231
|
-
<h4 className="mb-2 text-foreground">
|
|
1232
|
-
Fontes Consultadas
|
|
1233
|
-
</h4>
|
|
1234
|
-
<div className="flex flex-wrap gap-2 overflow-hidden">
|
|
1235
|
-
{msg.searchSources.map((source, index) => (
|
|
1236
|
-
<div
|
|
1237
|
-
key={index}
|
|
1238
|
-
className="px-3 py-1.5 border max-w-full rounded-[var(--radius-button)] bg-muted border-border"
|
|
1239
|
-
>
|
|
1240
|
-
<span className="text-sm font-medium text-foreground break-words">{source.name}</span>
|
|
1241
|
-
<span className="text-sm text-muted-foreground ml-1 whitespace-nowrap">({source.count})</span>
|
|
1242
|
-
</div>
|
|
1243
|
-
))}
|
|
1244
|
-
</div>
|
|
1245
|
-
</div>
|
|
1246
|
-
)}
|
|
1247
|
-
|
|
1248
|
-
{/* Search Commands */}
|
|
1249
|
-
{msg.searchCommands && msg.searchResults && (
|
|
1250
|
-
<div>
|
|
1251
|
-
<h4 className="mb-2 text-foreground">
|
|
1252
|
-
O que você pode fazer com estes resultados
|
|
1253
|
-
</h4>
|
|
1254
|
-
<div className="grid grid-cols-1 gap-2">
|
|
1255
|
-
{msg.searchCommands.map((command) => (
|
|
1256
|
-
<button
|
|
1257
|
-
key={command.id}
|
|
1258
|
-
onClick={() => handleExecuteSearchCommand(
|
|
1259
|
-
command.id,
|
|
1260
|
-
msg.content.replace('🔍 Pesquisa realizada com sucesso!', '').split('"')[1] || 'pesquisa',
|
|
1261
|
-
msg.searchResults!,
|
|
1262
|
-
msg.id
|
|
1263
|
-
)}
|
|
1264
|
-
disabled={executingCommand === command.id}
|
|
1265
|
-
className={cn(
|
|
1266
|
-
"flex items-start gap-2 p-2 rounded-[var(--radius)] border transition-all text-left disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1267
|
-
savedSearches.includes(msg.id) && command.id === '5'
|
|
1268
|
-
? "border-[var(--toast-warning-border)] bg-[var(--toast-warning-bg)]/20"
|
|
1269
|
-
: "border-border bg-transparent hover:bg-muted/50"
|
|
1270
|
-
)}
|
|
1271
|
-
>
|
|
1272
|
-
{executingCommand === command.id ? (
|
|
1273
|
-
<Loader2 className="w-5 h-5 animate-spin flex-shrink-0 text-primary" />
|
|
1274
|
-
) : (
|
|
1275
|
-
<span className="flex-shrink-0">{command.icon}</span>
|
|
1276
|
-
)}
|
|
1277
|
-
<div className="flex-1 min-w-0 overflow-hidden">
|
|
1278
|
-
<div className="text-sm font-medium text-foreground break-words">
|
|
1279
|
-
{command.id === '5' && savedSearches.includes(msg.id) ? '⭐ Pesquisa salva' : command.label}
|
|
1280
|
-
</div>
|
|
1281
|
-
<div className="text-sm text-muted-foreground break-words">
|
|
1282
|
-
{executingCommand === command.id ? 'Processando...' : command.description}
|
|
1283
|
-
</div>
|
|
1284
|
-
</div>
|
|
1285
|
-
</button>
|
|
1286
|
-
))}
|
|
1287
|
-
</div>
|
|
1288
|
-
</div>
|
|
1289
|
-
)}
|
|
1290
|
-
</div>
|
|
1291
|
-
)}
|
|
1292
|
-
</div>
|
|
1293
|
-
|
|
1294
|
-
{/* Message Actions */}
|
|
1295
|
-
<div className="flex items-center gap-2 mt-1 px-2">
|
|
1296
|
-
<span className="text-sm text-muted-foreground">
|
|
1297
|
-
{msg.timestamp.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' })}
|
|
1298
|
-
</span>
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
{enablePodcastGeneration && msg.type === 'assistant' && msg.attachmentType !== 'podcast' && (
|
|
1302
|
-
<Button
|
|
1303
|
-
variant="ghost"
|
|
1304
|
-
size="sm"
|
|
1305
|
-
onClick={() => handleGeneratePodcast(msg.id, msg.content)}
|
|
1306
|
-
disabled={generatingPodcastId === msg.id}
|
|
1307
|
-
className="h-6 w-6 p-0 disabled:opacity-50 text-muted-foreground"
|
|
1308
|
-
title="Gerar Podcast"
|
|
1309
|
-
aria-label="Gerar Podcast"
|
|
1310
|
-
>
|
|
1311
|
-
{generatingPodcastId === msg.id ? (
|
|
1312
|
-
<Loader2 className="w-3 h-3 animate-spin" />
|
|
1313
|
-
) : (
|
|
1314
|
-
<Radio className="w-3 h-3" />
|
|
1315
|
-
)}
|
|
1316
|
-
</Button>
|
|
1317
|
-
)}
|
|
1318
|
-
|
|
1319
|
-
{msg.type === 'assistant' && (
|
|
1320
|
-
<div className="flex items-center gap-1 border-l border-border pl-2 ml-1">
|
|
1321
|
-
<Button
|
|
1322
|
-
variant="ghost"
|
|
1323
|
-
size="icon"
|
|
1324
|
-
className={cn(
|
|
1325
|
-
"h-6 w-6 rounded-full hover:bg-green-100 dark:hover:bg-green-900/20 hover:text-green-600",
|
|
1326
|
-
msg.evaluation === 'like' && "text-green-600 bg-green-100 dark:bg-green-900/20"
|
|
1327
|
-
)}
|
|
1328
|
-
onClick={() => handleEvaluationClick(msg.id, 'like')}
|
|
1329
|
-
title="Gostei"
|
|
1330
|
-
aria-label="Gostei"
|
|
1331
|
-
>
|
|
1332
|
-
<ThumbsUp className="h-3.5 w-3.5" />
|
|
1333
|
-
</Button>
|
|
1334
|
-
|
|
1335
|
-
<DropdownMenu>
|
|
1336
|
-
<DropdownMenuTrigger asChild>
|
|
1337
|
-
<Button
|
|
1338
|
-
variant="ghost"
|
|
1339
|
-
size="icon"
|
|
1340
|
-
className={cn(
|
|
1341
|
-
"h-6 w-6 rounded-full hover:bg-red-100 dark:hover:bg-red-900/20 hover:text-red-600",
|
|
1342
|
-
msg.evaluation === 'dislike' && "text-red-600 bg-red-100 dark:bg-red-900/20"
|
|
1343
|
-
)}
|
|
1344
|
-
title="Não gostei"
|
|
1345
|
-
aria-label="Não gostei"
|
|
1346
|
-
>
|
|
1347
|
-
<ThumbsDown className="h-3.5 w-3.5" />
|
|
1348
|
-
</Button>
|
|
1349
|
-
</DropdownMenuTrigger>
|
|
1350
|
-
<DropdownMenuContent align="start">
|
|
1351
|
-
{feedbackOptions && feedbackOptions.length > 0 ? (
|
|
1352
|
-
feedbackOptions.map((option, idx) => (
|
|
1353
|
-
<DropdownMenuItem key={idx} onClick={() => openFeedbackDialog(msg.id, option)}>
|
|
1354
|
-
{option}
|
|
1355
|
-
</DropdownMenuItem>
|
|
1356
|
-
))
|
|
1357
|
-
) : (
|
|
1358
|
-
<>
|
|
1359
|
-
<DropdownMenuItem onClick={() => openFeedbackDialog(msg.id, 'Não era o que eu procurava')}>
|
|
1360
|
-
Não era o que eu procurava
|
|
1361
|
-
</DropdownMenuItem>
|
|
1362
|
-
<DropdownMenuItem onClick={() => openFeedbackDialog(msg.id, 'Informação incorreta')}>
|
|
1363
|
-
Informação incorreta
|
|
1364
|
-
</DropdownMenuItem>
|
|
1365
|
-
<DropdownMenuItem onClick={() => openFeedbackDialog(msg.id, 'Resposta incompleta')}>
|
|
1366
|
-
Resposta incompleta
|
|
1367
|
-
</DropdownMenuItem>
|
|
1368
|
-
</>
|
|
1369
|
-
)}
|
|
1370
|
-
<DropdownMenuItem onClick={() => openFeedbackDialog(msg.id, null)}>
|
|
1371
|
-
Outros...
|
|
1372
|
-
</DropdownMenuItem>
|
|
1373
|
-
</DropdownMenuContent>
|
|
1374
|
-
</DropdownMenu>
|
|
1375
|
-
</div>
|
|
1376
|
-
)}
|
|
1377
|
-
|
|
1378
|
-
<Button
|
|
1379
|
-
variant="ghost"
|
|
1380
|
-
size="sm"
|
|
1381
|
-
onClick={() => handleCopyMessage(msg.content, msg.id)}
|
|
1382
|
-
className={`h-6 w-6 p-0 ${copiedId === msg.id ? 'text-[var(--toast-success-icon)]' : 'text-muted-foreground'}`}
|
|
1383
|
-
aria-label={copiedId === msg.id ? "Copiado" : "Copiar mensagem"}
|
|
1384
|
-
>
|
|
1385
|
-
{copiedId === msg.id ? (
|
|
1386
|
-
<Check className="w-3 h-3" />
|
|
1387
|
-
) : (
|
|
1388
|
-
<Copy className="w-3 h-3" />
|
|
1389
|
-
)}
|
|
1390
|
-
</Button>
|
|
1391
|
-
</div>
|
|
1392
|
-
</div>
|
|
1393
|
-
</motion.div>
|
|
525
|
+
msg={msg}
|
|
526
|
+
copiedId={copiedId}
|
|
527
|
+
generatingPodcastId={generatingPodcastId}
|
|
528
|
+
executingCommand={executingCommand}
|
|
529
|
+
savedSearches={savedSearches}
|
|
530
|
+
enablePodcastGeneration={enablePodcastGeneration}
|
|
531
|
+
feedbackOptions={feedbackOptions}
|
|
532
|
+
onCopyMessage={handleCopyMessage}
|
|
533
|
+
onToggleFavorite={handleToggleFavorite}
|
|
534
|
+
onGeneratePodcast={handleGeneratePodcast}
|
|
535
|
+
onDownloadDocument={handleDownloadDocument}
|
|
536
|
+
onDownloadPodcast={handleDownloadPodcast}
|
|
537
|
+
onEditDocument={handleEditDocument}
|
|
538
|
+
onOpenSearchResult={handleOpenSearchResult}
|
|
539
|
+
onExecuteSearchCommand={handleExecuteSearchCommand}
|
|
540
|
+
onEvaluationClick={handleEvaluationClick}
|
|
541
|
+
onOpenFeedbackDialog={openFeedbackDialog}
|
|
542
|
+
/>
|
|
1394
543
|
))}
|
|
1395
544
|
|
|
1396
545
|
{/* Typing Indicator */}
|
|
1397
|
-
{isProcessing &&
|
|
1398
|
-
<motion.div
|
|
1399
|
-
initial={{ opacity: 0, y: 10 }}
|
|
1400
|
-
animate={{ opacity: 1, y: 0 }}
|
|
1401
|
-
className="flex gap-2 justify-start"
|
|
1402
|
-
>
|
|
1403
|
-
{/* Avatar do Assistente */}
|
|
1404
|
-
<div className="flex-shrink-0 pt-1">
|
|
1405
|
-
<XerticaOrbe size={32} />
|
|
1406
|
-
</div>
|
|
1407
|
-
|
|
1408
|
-
<div
|
|
1409
|
-
className="px-4 py-3 bg-muted rounded-2xl"
|
|
1410
|
-
>
|
|
1411
|
-
<div className="flex gap-1">
|
|
1412
|
-
<motion.div
|
|
1413
|
-
className="w-2 h-2 rounded-full bg-muted-foreground"
|
|
1414
|
-
animate={{ y: [0, -8, 0] }}
|
|
1415
|
-
transition={{ repeat: Infinity, duration: 0.6, delay: 0 }}
|
|
1416
|
-
/>
|
|
1417
|
-
<motion.div
|
|
1418
|
-
className="w-2 h-2 rounded-full bg-muted-foreground"
|
|
1419
|
-
animate={{ y: [0, -8, 0] }}
|
|
1420
|
-
transition={{ repeat: Infinity, duration: 0.6, delay: 0.2 }}
|
|
1421
|
-
/>
|
|
1422
|
-
<motion.div
|
|
1423
|
-
className="w-2 h-2 rounded-full bg-muted-foreground"
|
|
1424
|
-
animate={{ y: [0, -8, 0] }}
|
|
1425
|
-
transition={{ repeat: Infinity, duration: 0.6, delay: 0.4 }}
|
|
1426
|
-
/>
|
|
1427
|
-
</div>
|
|
1428
|
-
</div>
|
|
1429
|
-
</motion.div>
|
|
1430
|
-
)}
|
|
546
|
+
{isProcessing && <AssistantTypingIndicator />}
|
|
1431
547
|
|
|
1432
548
|
<div ref={messagesEndRef} />
|
|
1433
549
|
</div>
|
|
@@ -1436,82 +552,21 @@ export function XerticaAssistant({
|
|
|
1436
552
|
</div>
|
|
1437
553
|
)}
|
|
1438
554
|
|
|
555
|
+
{/* History / Favorites Tab */}
|
|
1439
556
|
{((abaSelecionada === 'historico' && showHistory) || (abaSelecionada === 'favoritos' && showFavorites)) && (
|
|
1440
|
-
<
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
<Plus className="w-4 h-4 mr-2" />
|
|
1450
|
-
Nova Conversa
|
|
1451
|
-
</Button>
|
|
1452
|
-
|
|
1453
|
-
{/* Conversations List */}
|
|
1454
|
-
<div className="space-y-2">
|
|
1455
|
-
{conversasFiltradas.length === 0 ? (
|
|
1456
|
-
<div className="text-center py-8">
|
|
1457
|
-
<Heart className="w-12 h-12 mx-auto text-muted-foreground/50 mb-2" />
|
|
1458
|
-
<p className="text-muted-foreground">
|
|
1459
|
-
{abaSelecionada === 'favoritos'
|
|
1460
|
-
? 'Nenhuma conversa favorita ainda'
|
|
1461
|
-
: 'Nenhuma conversa no histórico'}
|
|
1462
|
-
</p>
|
|
1463
|
-
</div>
|
|
1464
|
-
) : (
|
|
1465
|
-
conversasFiltradas.map((conversa) => (
|
|
1466
|
-
<div
|
|
1467
|
-
key={conversa.id}
|
|
1468
|
-
onClick={() => handleSelecionarConversa(conversa.id)}
|
|
1469
|
-
className={cn(
|
|
1470
|
-
"p-3 rounded-[var(--radius)] cursor-pointer transition-colors duration-200 border",
|
|
1471
|
-
conversa.id === conversaAtual
|
|
1472
|
-
? "border-primary bg-primary/10"
|
|
1473
|
-
: "border-border hover:bg-muted"
|
|
1474
|
-
)}
|
|
1475
|
-
>
|
|
1476
|
-
<div className="flex items-start justify-between mb-1">
|
|
1477
|
-
<h4 className="text-sm font-medium text-foreground truncate flex-1">
|
|
1478
|
-
{conversa.title}
|
|
1479
|
-
</h4>
|
|
1480
|
-
<Button
|
|
1481
|
-
variant="ghost"
|
|
1482
|
-
size="sm"
|
|
1483
|
-
onClick={(e) => {
|
|
1484
|
-
e.stopPropagation();
|
|
1485
|
-
handleToggleFavoritaConversa(conversa.id);
|
|
1486
|
-
}}
|
|
1487
|
-
className="h-6 w-6 p-0 flex-shrink-0 ml-1"
|
|
1488
|
-
>
|
|
1489
|
-
<Heart
|
|
1490
|
-
className={cn(
|
|
1491
|
-
"w-3 h-3",
|
|
1492
|
-
conversa.isFavorite ? "text-destructive fill-current" : "text-muted-foreground"
|
|
1493
|
-
)}
|
|
1494
|
-
/>
|
|
1495
|
-
</Button>
|
|
1496
|
-
</div>
|
|
1497
|
-
{conversa.lastMessage && (
|
|
1498
|
-
<p className="text-sm text-muted-foreground truncate mb-1">
|
|
1499
|
-
{conversa.lastMessage}
|
|
1500
|
-
</p>
|
|
1501
|
-
)}
|
|
1502
|
-
<p className="text-sm text-muted-foreground">
|
|
1503
|
-
{conversa.timestamp}
|
|
1504
|
-
</p>
|
|
1505
|
-
</div>
|
|
1506
|
-
))
|
|
1507
|
-
)}
|
|
1508
|
-
</div>
|
|
1509
|
-
</div>
|
|
1510
|
-
</ScrollArea>
|
|
557
|
+
<AssistantConversationList
|
|
558
|
+
conversations={conversasFiltradas}
|
|
559
|
+
currentConversationId={conversaAtual}
|
|
560
|
+
activeTab={abaSelecionada}
|
|
561
|
+
isFullPage={isFullPage}
|
|
562
|
+
onNewConversation={handleNovaConversa}
|
|
563
|
+
onSelectConversation={handleSelecionarConversa}
|
|
564
|
+
onToggleFavorite={handleToggleFavoritaConversa}
|
|
565
|
+
/>
|
|
1511
566
|
)}
|
|
1512
567
|
</div>
|
|
1513
568
|
|
|
1514
|
-
{/* Modern Input Area
|
|
569
|
+
{/* Modern Input Area — only visible in chat mode */}
|
|
1515
570
|
{abaSelecionada === 'chat' && (
|
|
1516
571
|
<ModernChatInput
|
|
1517
572
|
value={mensagem}
|
|
@@ -1535,38 +590,12 @@ export function XerticaAssistant({
|
|
|
1535
590
|
</div>
|
|
1536
591
|
|
|
1537
592
|
{/* Feedback Dialog */}
|
|
1538
|
-
<
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
<DialogDescription>
|
|
1545
|
-
{evaluationState.category
|
|
1546
|
-
? "Gostaria de adicionar algum comentário? (Opcional)"
|
|
1547
|
-
: "Conte-nos por que essa resposta não foi útil para que possamos melhorar."}
|
|
1548
|
-
</DialogDescription>
|
|
1549
|
-
</DialogHeader>
|
|
1550
|
-
<div className="grid gap-4 py-4 px-6">
|
|
1551
|
-
<Textarea
|
|
1552
|
-
className="min-h-[100px]"
|
|
1553
|
-
placeholder={evaluationState.category ? "Comentário adicional..." : "Descreva o motivo..."}
|
|
1554
|
-
aria-label={evaluationState.category ? "Comentário adicional" : "Descreva o motivo"}
|
|
1555
|
-
value={evaluationState.reason}
|
|
1556
|
-
onChange={(e) => setEvaluationState(prev => ({ ...prev, reason: e.target.value }))}
|
|
1557
|
-
rows={4}
|
|
1558
|
-
/>
|
|
1559
|
-
</div>
|
|
1560
|
-
<DialogFooter>
|
|
1561
|
-
<Button variant="outline" onClick={() => setEvaluationState(prev => ({ ...prev, isOpen: false }))}>
|
|
1562
|
-
Cancelar
|
|
1563
|
-
</Button>
|
|
1564
|
-
<Button onClick={handleSubmitDislike} disabled={!evaluationState.category && !evaluationState.reason.trim()}>
|
|
1565
|
-
{evaluationState.category ? 'Confirmar e Enviar' : 'Enviar Feedback'}
|
|
1566
|
-
</Button>
|
|
1567
|
-
</DialogFooter>
|
|
1568
|
-
</DialogContent>
|
|
1569
|
-
</Dialog>
|
|
593
|
+
<AssistantFeedbackDialog
|
|
594
|
+
state={evaluationState}
|
|
595
|
+
onReasonChange={(reason) => setEvaluationState(prev => ({ ...prev, reason }))}
|
|
596
|
+
onClose={() => setEvaluationState(prev => ({ ...prev, isOpen: false }))}
|
|
597
|
+
onSubmit={handleSubmitDislike}
|
|
598
|
+
/>
|
|
1570
599
|
</>
|
|
1571
600
|
);
|
|
1572
601
|
}
|