xertica-ui 1.3.3 → 1.3.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/components/HomePage.tsx +21 -8
- package/components/ui/xertica-assistant.tsx +329 -30
- package/dist/components/HomePage.d.ts +0 -6
- package/dist/components/ui/xertica-assistant.d.ts +23 -1
- package/dist/index.es.js +44538 -44394
- package/dist/index.umd.js +44472 -44328
- package/dist/utils/demo-responses.d.ts +2 -0
- package/package.json +1 -1
- package/tsconfig.json +22 -8
- package/utils/demo-responses.ts +115 -0
package/components/HomePage.tsx
CHANGED
|
@@ -2,15 +2,24 @@ import React from 'react';
|
|
|
2
2
|
import { useLocation, useNavigate } from 'react-router';
|
|
3
3
|
import { Sidebar } from './Sidebar';
|
|
4
4
|
import { HomeContent } from './HomeContent';
|
|
5
|
-
import {
|
|
5
|
+
import { XerticaAssistant } from './ui/xertica-assistant';
|
|
6
|
+
import { generateDemoResponse } from '../utils/demo-responses';
|
|
6
7
|
import { routes } from '../routes';
|
|
8
|
+
import { useLayout } from '../contexts/LayoutContext';
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
10
|
+
const richSuggestions = [
|
|
11
|
+
{ id: 'chart-1', texto: 'Ver análise de performance' },
|
|
12
|
+
{ id: 'table-1', texto: 'Gerar relatório de projetos' },
|
|
13
|
+
{ id: 'doc-1', texto: 'Criar documento de requisitos' },
|
|
14
|
+
{ id: 'pod-1', texto: 'Gerar podcast do resumo diário' }
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const feedbackOptions = [
|
|
18
|
+
'Não era o que eu procurava',
|
|
19
|
+
'Informação incorreta',
|
|
20
|
+
'Resposta incompleta'
|
|
21
|
+
];
|
|
12
22
|
|
|
13
|
-
import { useLayout } from '../contexts/LayoutContext';
|
|
14
23
|
|
|
15
24
|
interface HomePageProps {
|
|
16
25
|
user: { email: string } | null;
|
|
@@ -34,10 +43,14 @@ export function HomePage({ user, onLogout }: HomePageProps) {
|
|
|
34
43
|
routes={routes}
|
|
35
44
|
/>
|
|
36
45
|
<HomeContent />
|
|
37
|
-
<
|
|
46
|
+
<XerticaAssistant
|
|
38
47
|
isExpanded={assistenteExpanded}
|
|
39
48
|
onToggle={toggleAssistente}
|
|
40
|
-
|
|
49
|
+
defaultTab="chat"
|
|
50
|
+
demoMode={true}
|
|
51
|
+
responseGenerator={generateDemoResponse}
|
|
52
|
+
richSuggestions={richSuggestions}
|
|
53
|
+
feedbackOptions={feedbackOptions}
|
|
41
54
|
/>
|
|
42
55
|
</div>
|
|
43
56
|
);
|
|
@@ -31,8 +31,52 @@ import {
|
|
|
31
31
|
BarChart3,
|
|
32
32
|
Bookmark,
|
|
33
33
|
Maximize2,
|
|
34
|
-
AlertCircle
|
|
34
|
+
AlertCircle,
|
|
35
|
+
ThumbsUp,
|
|
36
|
+
ThumbsDown,
|
|
37
|
+
Table as TableIcon,
|
|
38
|
+
ArrowLeft
|
|
35
39
|
} from 'lucide-react';
|
|
40
|
+
import {
|
|
41
|
+
Bar,
|
|
42
|
+
BarChart,
|
|
43
|
+
CartesianGrid,
|
|
44
|
+
XAxis,
|
|
45
|
+
Tooltip as RechartsTooltip,
|
|
46
|
+
ResponsiveContainer
|
|
47
|
+
} from "recharts";
|
|
48
|
+
import {
|
|
49
|
+
ChartConfig,
|
|
50
|
+
ChartContainer,
|
|
51
|
+
ChartTooltip,
|
|
52
|
+
ChartTooltipContent,
|
|
53
|
+
ChartLegend,
|
|
54
|
+
ChartLegendContent
|
|
55
|
+
} from "./chart";
|
|
56
|
+
import {
|
|
57
|
+
Table,
|
|
58
|
+
TableBody,
|
|
59
|
+
TableCaption,
|
|
60
|
+
TableCell,
|
|
61
|
+
TableHead,
|
|
62
|
+
TableHeader,
|
|
63
|
+
TableRow,
|
|
64
|
+
} from "./table";
|
|
65
|
+
import {
|
|
66
|
+
Dialog,
|
|
67
|
+
DialogContent,
|
|
68
|
+
DialogDescription,
|
|
69
|
+
DialogFooter,
|
|
70
|
+
DialogHeader,
|
|
71
|
+
DialogTitle,
|
|
72
|
+
} from "./dialog";
|
|
73
|
+
import {
|
|
74
|
+
DropdownMenu,
|
|
75
|
+
DropdownMenuContent,
|
|
76
|
+
DropdownMenuItem,
|
|
77
|
+
DropdownMenuTrigger,
|
|
78
|
+
} from "./dropdown-menu";
|
|
79
|
+
import { Textarea } from "./textarea";
|
|
36
80
|
import { Button } from './button';
|
|
37
81
|
import { ScrollArea } from './scroll-area';
|
|
38
82
|
import { Separator } from './separator';
|
|
@@ -295,6 +339,28 @@ export interface XerticaAssistantProps {
|
|
|
295
339
|
*/
|
|
296
340
|
className?: string;
|
|
297
341
|
mobileFloating?: boolean;
|
|
342
|
+
/**
|
|
343
|
+
* Função para gerar respostas customizadas
|
|
344
|
+
* @param message A mensagem do usuário
|
|
345
|
+
* @returns Promessa com a resposta ou a resposta diretamente
|
|
346
|
+
*/
|
|
347
|
+
responseGenerator?: (message: string) => Promise<string | Partial<Message>> | string | Partial<Message>;
|
|
348
|
+
/**
|
|
349
|
+
* Sugestões ricas adicionais (exibidas ao clicar em "Mais sugestões")
|
|
350
|
+
*/
|
|
351
|
+
richSuggestions?: Suggestion[];
|
|
352
|
+
/**
|
|
353
|
+
* Callback para ações de sugestão rica
|
|
354
|
+
*/
|
|
355
|
+
onRichAction?: (actionId: string, actionText: string) => void;
|
|
356
|
+
/**
|
|
357
|
+
* Callback para avaliação de mensagens
|
|
358
|
+
*/
|
|
359
|
+
onEvaluation?: (messageId: string, type: 'like' | 'dislike', reason?: string) => void;
|
|
360
|
+
/**
|
|
361
|
+
* Opções de feedback negativo (exibidas no dropdown de dislike)
|
|
362
|
+
*/
|
|
363
|
+
feedbackOptions?: string[];
|
|
298
364
|
}
|
|
299
365
|
|
|
300
366
|
// ============================================================================
|
|
@@ -353,7 +419,12 @@ export function XerticaAssistant({
|
|
|
353
419
|
className = '',
|
|
354
420
|
mobileFloating = false,
|
|
355
421
|
demoMode = false,
|
|
356
|
-
customResponses = []
|
|
422
|
+
customResponses = [],
|
|
423
|
+
responseGenerator,
|
|
424
|
+
richSuggestions = [],
|
|
425
|
+
onRichAction,
|
|
426
|
+
onEvaluation,
|
|
427
|
+
feedbackOptions
|
|
357
428
|
}: XerticaAssistantProps) {
|
|
358
429
|
// ============================================================================
|
|
359
430
|
// State Management
|
|
@@ -376,6 +447,20 @@ export function XerticaAssistant({
|
|
|
376
447
|
content: string;
|
|
377
448
|
title: string;
|
|
378
449
|
} | null>(null);
|
|
450
|
+
const [showMoreSuggestions, setShowMoreSuggestions] = useState(false);
|
|
451
|
+
const [evaluationState, setEvaluationState] = useState<{
|
|
452
|
+
isOpen: boolean;
|
|
453
|
+
messageId: string | null;
|
|
454
|
+
type: 'dislike' | null;
|
|
455
|
+
category?: string | null;
|
|
456
|
+
reason: string;
|
|
457
|
+
}>({
|
|
458
|
+
isOpen: false,
|
|
459
|
+
messageId: null,
|
|
460
|
+
type: null,
|
|
461
|
+
category: null,
|
|
462
|
+
reason: ''
|
|
463
|
+
});
|
|
379
464
|
|
|
380
465
|
// ============================================================================
|
|
381
466
|
// Refs
|
|
@@ -446,13 +531,20 @@ export function XerticaAssistant({
|
|
|
446
531
|
}
|
|
447
532
|
};
|
|
448
533
|
|
|
449
|
-
const handleEnviarMensagem = async () => {
|
|
450
|
-
|
|
534
|
+
const handleEnviarMensagem = async (arg?: string | ActionType) => {
|
|
535
|
+
let msgToSend = mensagem;
|
|
536
|
+
|
|
537
|
+
// Check if argument is a message text (from simple string) or ActionType
|
|
538
|
+
if (typeof arg === 'string' && !['document', 'podcast', 'search'].includes(arg)) {
|
|
539
|
+
msgToSend = arg;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if (!msgToSend.trim() || isProcessing) return;
|
|
451
543
|
|
|
452
544
|
const novaMensagem: Message = {
|
|
453
545
|
id: `msg-${Date.now()}`,
|
|
454
546
|
type: 'user',
|
|
455
|
-
content:
|
|
547
|
+
content: msgToSend,
|
|
456
548
|
timestamp: new Date(),
|
|
457
549
|
isFavorite: false,
|
|
458
550
|
};
|
|
@@ -461,16 +553,19 @@ export function XerticaAssistant({
|
|
|
461
553
|
|
|
462
554
|
|
|
463
555
|
if (onSendMessage) {
|
|
464
|
-
onSendMessage(
|
|
556
|
+
onSendMessage(msgToSend);
|
|
465
557
|
}
|
|
466
558
|
|
|
467
|
-
if (demoMode) {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
559
|
+
if (demoMode || responseGenerator) {
|
|
560
|
+
const mensagemAtual = msgToSend;
|
|
561
|
+
setTimeout(async () => {
|
|
562
|
+
let resposta: string | Partial<Message>;
|
|
563
|
+
|
|
564
|
+
if (responseGenerator) {
|
|
565
|
+
resposta = await responseGenerator(mensagemAtual);
|
|
566
|
+
} else {
|
|
567
|
+
resposta = gerarResposta(mensagemAtual, customResponses);
|
|
568
|
+
}
|
|
474
569
|
|
|
475
570
|
let novaMensagemIA: Message = {
|
|
476
571
|
id: `msg-${Date.now()}-ia`,
|
|
@@ -637,6 +732,48 @@ export function XerticaAssistant({
|
|
|
637
732
|
}, 1500);
|
|
638
733
|
};
|
|
639
734
|
|
|
735
|
+
const handleRichSuggestionClick = (suggestion: Suggestion) => {
|
|
736
|
+
if (onRichAction) {
|
|
737
|
+
onRichAction(suggestion.id, suggestion.texto);
|
|
738
|
+
} else {
|
|
739
|
+
// Fallback: send as message
|
|
740
|
+
handleEnviarMensagem(suggestion.texto);
|
|
741
|
+
}
|
|
742
|
+
setShowMoreSuggestions(false);
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
const handleEvaluationClick = (messageId: string, type: 'like' | 'dislike') => {
|
|
746
|
+
if (type === 'like') {
|
|
747
|
+
if (onEvaluation) onEvaluation(messageId, 'like');
|
|
748
|
+
// Update local state
|
|
749
|
+
setMensagens(prev => prev.map(m => m.id === messageId ? { ...m, evaluation: 'like' } : m));
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
|
|
753
|
+
const openFeedbackDialog = (messageId: string, category: string | null) => {
|
|
754
|
+
setEvaluationState({
|
|
755
|
+
isOpen: true,
|
|
756
|
+
messageId,
|
|
757
|
+
type: 'dislike',
|
|
758
|
+
category,
|
|
759
|
+
reason: ''
|
|
760
|
+
});
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
const handleSubmitDislike = () => {
|
|
764
|
+
if (evaluationState.messageId && onEvaluation) {
|
|
765
|
+
const finalReason = evaluationState.category
|
|
766
|
+
? (evaluationState.reason ? `${evaluationState.category}: ${evaluationState.reason}` : evaluationState.category)
|
|
767
|
+
: evaluationState.reason;
|
|
768
|
+
|
|
769
|
+
onEvaluation(evaluationState.messageId, 'dislike', finalReason);
|
|
770
|
+
|
|
771
|
+
// Update local state
|
|
772
|
+
setMensagens(prev => prev.map(m => m.id === evaluationState.messageId ? { ...m, evaluation: 'dislike', evaluationReason: finalReason } : m));
|
|
773
|
+
}
|
|
774
|
+
setEvaluationState({ isOpen: false, messageId: null, type: null, category: null, reason: '' });
|
|
775
|
+
};
|
|
776
|
+
|
|
640
777
|
// ============================================================================
|
|
641
778
|
// Computations
|
|
642
779
|
// ============================================================================
|
|
@@ -986,21 +1123,53 @@ export function XerticaAssistant({
|
|
|
986
1123
|
{sugestoes.map((sugestao) => (
|
|
987
1124
|
<button
|
|
988
1125
|
key={sugestao.id}
|
|
989
|
-
onClick={() =>
|
|
1126
|
+
onClick={() => handleEnviarMensagem(sugestao.texto)}
|
|
990
1127
|
className="w-full p-3 text-left rounded-[var(--radius-card)] bg-muted text-foreground transition-colors duration-200 hover:bg-muted/80"
|
|
991
1128
|
>
|
|
992
1129
|
{sugestao.texto}
|
|
993
1130
|
</button>
|
|
994
1131
|
))}
|
|
995
1132
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1133
|
+
{!showMoreSuggestions ? (
|
|
1134
|
+
<Button
|
|
1135
|
+
variant="ghost"
|
|
1136
|
+
size="sm"
|
|
1137
|
+
onClick={() => setShowMoreSuggestions(true)}
|
|
1138
|
+
className="w-full justify-start text-muted-foreground"
|
|
1139
|
+
>
|
|
1140
|
+
<MoreHorizontal className="w-4 h-4 mr-2" />
|
|
1141
|
+
Mais sugestões
|
|
1142
|
+
</Button>
|
|
1143
|
+
) : (
|
|
1144
|
+
<div className="space-y-2 pt-2 border-t border-border mt-2 animate-in slide-in-from-top-2">
|
|
1145
|
+
{richSuggestions.length > 0 ? (
|
|
1146
|
+
richSuggestions.map((sugestao) => (
|
|
1147
|
+
<button
|
|
1148
|
+
key={sugestao.id}
|
|
1149
|
+
onClick={() => handleRichSuggestionClick(sugestao)}
|
|
1150
|
+
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"
|
|
1151
|
+
>
|
|
1152
|
+
<div className="flex items-center gap-2">
|
|
1153
|
+
{sugestao.id.includes('chart') && <BarChart3 className="w-4 h-4 text-primary" />}
|
|
1154
|
+
{sugestao.id.includes('table') && <TableIcon className="w-4 h-4 text-primary" />}
|
|
1155
|
+
<span className="font-medium">{sugestao.texto}</span>
|
|
1156
|
+
</div>
|
|
1157
|
+
</button>
|
|
1158
|
+
))
|
|
1159
|
+
) : (
|
|
1160
|
+
<p className="text-sm text-muted-foreground text-center py-2">Nenhuma sugestão extra.</p>
|
|
1161
|
+
)}
|
|
1162
|
+
<Button
|
|
1163
|
+
variant="ghost"
|
|
1164
|
+
size="sm"
|
|
1165
|
+
onClick={() => setShowMoreSuggestions(false)}
|
|
1166
|
+
className="w-full justify-center text-muted-foreground mt-2"
|
|
1167
|
+
>
|
|
1168
|
+
<ChevronLeft className="w-4 h-4 mr-2" />
|
|
1169
|
+
Voltar
|
|
1170
|
+
</Button>
|
|
1171
|
+
</div>
|
|
1172
|
+
)}
|
|
1004
1173
|
</div>
|
|
1005
1174
|
</div>
|
|
1006
1175
|
) : (
|
|
@@ -1105,6 +1274,54 @@ export function XerticaAssistant({
|
|
|
1105
1274
|
</>
|
|
1106
1275
|
)}
|
|
1107
1276
|
|
|
1277
|
+
{/* Chart Rendering */}
|
|
1278
|
+
{msg.chartData && msg.chartConfig && (
|
|
1279
|
+
<div className="mt-4 w-full h-[300px] min-w-[300px]">
|
|
1280
|
+
<ChartContainer config={msg.chartConfig} className="h-full w-full">
|
|
1281
|
+
<BarChart accessibilityLayer data={msg.chartData}>
|
|
1282
|
+
<CartesianGrid vertical={false} />
|
|
1283
|
+
<XAxis
|
|
1284
|
+
dataKey="month"
|
|
1285
|
+
tickLine={false}
|
|
1286
|
+
tickMargin={10}
|
|
1287
|
+
axisLine={false}
|
|
1288
|
+
tickFormatter={(value) => value.slice(0, 3)}
|
|
1289
|
+
/>
|
|
1290
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
1291
|
+
<ChartLegend content={<ChartLegendContent />} />
|
|
1292
|
+
{Object.keys(msg.chartConfig).map((key) => (
|
|
1293
|
+
<Bar key={key} dataKey={key} fill={`var(--color-${key})`} radius={4} />
|
|
1294
|
+
))}
|
|
1295
|
+
</BarChart>
|
|
1296
|
+
</ChartContainer>
|
|
1297
|
+
</div>
|
|
1298
|
+
)}
|
|
1299
|
+
|
|
1300
|
+
{/* Table Rendering */}
|
|
1301
|
+
{msg.tableData && (
|
|
1302
|
+
<div className="mt-4 w-full border rounded-[var(--radius)] overflow-hidden">
|
|
1303
|
+
<Table>
|
|
1304
|
+
{msg.tableData.caption && <TableCaption>{msg.tableData.caption}</TableCaption>}
|
|
1305
|
+
<TableHeader>
|
|
1306
|
+
<TableRow>
|
|
1307
|
+
{msg.tableData.headers.map((header, i) => (
|
|
1308
|
+
<TableHead key={i}>{header}</TableHead>
|
|
1309
|
+
))}
|
|
1310
|
+
</TableRow>
|
|
1311
|
+
</TableHeader>
|
|
1312
|
+
<TableBody>
|
|
1313
|
+
{msg.tableData.rows.map((row, i) => (
|
|
1314
|
+
<TableRow key={i}>
|
|
1315
|
+
{row.map((cell, j) => (
|
|
1316
|
+
<TableCell key={j}>{cell}</TableCell>
|
|
1317
|
+
))}
|
|
1318
|
+
</TableRow>
|
|
1319
|
+
))}
|
|
1320
|
+
</TableBody>
|
|
1321
|
+
</Table>
|
|
1322
|
+
</div>
|
|
1323
|
+
)}
|
|
1324
|
+
|
|
1108
1325
|
{/* Document Preview */}
|
|
1109
1326
|
{msg.attachmentType === 'document' && msg.documentContent && (
|
|
1110
1327
|
<div
|
|
@@ -1291,14 +1508,6 @@ export function XerticaAssistant({
|
|
|
1291
1508
|
{msg.timestamp.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' })}
|
|
1292
1509
|
</span>
|
|
1293
1510
|
|
|
1294
|
-
<Button
|
|
1295
|
-
variant="ghost"
|
|
1296
|
-
size="sm"
|
|
1297
|
-
onClick={() => handleToggleFavorite(msg.id)}
|
|
1298
|
-
className={`h-6 w-6 p-0 ${msg.isFavorite ? 'text-destructive' : 'text-muted-foreground'}`}
|
|
1299
|
-
>
|
|
1300
|
-
<Heart className={`w-3 h-3 ${msg.isFavorite ? 'fill-current' : ''}`} />
|
|
1301
|
-
</Button>
|
|
1302
1511
|
|
|
1303
1512
|
{msg.type === 'assistant' && msg.attachmentType !== 'podcast' && (
|
|
1304
1513
|
<Button
|
|
@@ -1317,6 +1526,63 @@ export function XerticaAssistant({
|
|
|
1317
1526
|
</Button>
|
|
1318
1527
|
)}
|
|
1319
1528
|
|
|
1529
|
+
{msg.type === 'assistant' && (
|
|
1530
|
+
<div className="flex items-center gap-1 border-l border-border pl-2 ml-1">
|
|
1531
|
+
<Button
|
|
1532
|
+
variant="ghost"
|
|
1533
|
+
size="icon"
|
|
1534
|
+
className={cn(
|
|
1535
|
+
"h-6 w-6 rounded-full hover:bg-green-100 dark:hover:bg-green-900/20 hover:text-green-600",
|
|
1536
|
+
msg.evaluation === 'like' && "text-green-600 bg-green-100 dark:bg-green-900/20"
|
|
1537
|
+
)}
|
|
1538
|
+
onClick={() => handleEvaluationClick(msg.id, 'like')}
|
|
1539
|
+
title="Gostei"
|
|
1540
|
+
>
|
|
1541
|
+
<ThumbsUp className="h-3.5 w-3.5" />
|
|
1542
|
+
</Button>
|
|
1543
|
+
|
|
1544
|
+
<DropdownMenu>
|
|
1545
|
+
<DropdownMenuTrigger asChild>
|
|
1546
|
+
<Button
|
|
1547
|
+
variant="ghost"
|
|
1548
|
+
size="icon"
|
|
1549
|
+
className={cn(
|
|
1550
|
+
"h-6 w-6 rounded-full hover:bg-red-100 dark:hover:bg-red-900/20 hover:text-red-600",
|
|
1551
|
+
msg.evaluation === 'dislike' && "text-red-600 bg-red-100 dark:bg-red-900/20"
|
|
1552
|
+
)}
|
|
1553
|
+
title="Não gostei"
|
|
1554
|
+
>
|
|
1555
|
+
<ThumbsDown className="h-3.5 w-3.5" />
|
|
1556
|
+
</Button>
|
|
1557
|
+
</DropdownMenuTrigger>
|
|
1558
|
+
<DropdownMenuContent align="start">
|
|
1559
|
+
{feedbackOptions && feedbackOptions.length > 0 ? (
|
|
1560
|
+
feedbackOptions.map((option, idx) => (
|
|
1561
|
+
<DropdownMenuItem key={idx} onClick={() => openFeedbackDialog(msg.id, option)}>
|
|
1562
|
+
{option}
|
|
1563
|
+
</DropdownMenuItem>
|
|
1564
|
+
))
|
|
1565
|
+
) : (
|
|
1566
|
+
<>
|
|
1567
|
+
<DropdownMenuItem onClick={() => openFeedbackDialog(msg.id, 'Não era o que eu procurava')}>
|
|
1568
|
+
Não era o que eu procurava
|
|
1569
|
+
</DropdownMenuItem>
|
|
1570
|
+
<DropdownMenuItem onClick={() => openFeedbackDialog(msg.id, 'Informação incorreta')}>
|
|
1571
|
+
Informação incorreta
|
|
1572
|
+
</DropdownMenuItem>
|
|
1573
|
+
<DropdownMenuItem onClick={() => openFeedbackDialog(msg.id, 'Resposta incompleta')}>
|
|
1574
|
+
Resposta incompleta
|
|
1575
|
+
</DropdownMenuItem>
|
|
1576
|
+
</>
|
|
1577
|
+
)}
|
|
1578
|
+
<DropdownMenuItem onClick={() => openFeedbackDialog(msg.id, null)}>
|
|
1579
|
+
Outros...
|
|
1580
|
+
</DropdownMenuItem>
|
|
1581
|
+
</DropdownMenuContent>
|
|
1582
|
+
</DropdownMenu>
|
|
1583
|
+
</div>
|
|
1584
|
+
)}
|
|
1585
|
+
|
|
1320
1586
|
<Button
|
|
1321
1587
|
variant="ghost"
|
|
1322
1588
|
size="sm"
|
|
@@ -1469,6 +1735,39 @@ export function XerticaAssistant({
|
|
|
1469
1735
|
)}
|
|
1470
1736
|
</AnimatePresence>
|
|
1471
1737
|
</div>
|
|
1738
|
+
|
|
1739
|
+
{/* Feedback Dialog */}
|
|
1740
|
+
<Dialog open={evaluationState.isOpen} onOpenChange={(open) => !open && setEvaluationState(prev => ({ ...prev, isOpen: false }))}>
|
|
1741
|
+
<DialogContent className="sm:max-w-[600px]">
|
|
1742
|
+
<DialogHeader>
|
|
1743
|
+
<DialogTitle className="pr-8">
|
|
1744
|
+
{evaluationState.category ? `Enviar feedback: ${evaluationState.category}` : 'Enviar feedback'}
|
|
1745
|
+
</DialogTitle>
|
|
1746
|
+
<DialogDescription>
|
|
1747
|
+
{evaluationState.category
|
|
1748
|
+
? "Gostaria de adicionar algum comentário? (Opcional)"
|
|
1749
|
+
: "Conte-nos por que essa resposta não foi útil para que possamos melhorar."}
|
|
1750
|
+
</DialogDescription>
|
|
1751
|
+
</DialogHeader>
|
|
1752
|
+
<div className="grid gap-4 py-4 px-6">
|
|
1753
|
+
<Textarea
|
|
1754
|
+
className="min-h-[100px]"
|
|
1755
|
+
placeholder={evaluationState.category ? "Comentário adicional..." : "Descreva o motivo..."}
|
|
1756
|
+
value={evaluationState.reason}
|
|
1757
|
+
onChange={(e) => setEvaluationState(prev => ({ ...prev, reason: e.target.value }))}
|
|
1758
|
+
rows={4}
|
|
1759
|
+
/>
|
|
1760
|
+
</div>
|
|
1761
|
+
<DialogFooter>
|
|
1762
|
+
<Button variant="outline" onClick={() => setEvaluationState(prev => ({ ...prev, isOpen: false }))}>
|
|
1763
|
+
Cancelar
|
|
1764
|
+
</Button>
|
|
1765
|
+
<Button onClick={handleSubmitDislike} disabled={!evaluationState.category && !evaluationState.reason.trim()}>
|
|
1766
|
+
{evaluationState.category ? 'Confirmar e Enviar' : 'Enviar Feedback'}
|
|
1767
|
+
</Button>
|
|
1768
|
+
</DialogFooter>
|
|
1769
|
+
</DialogContent>
|
|
1770
|
+
</Dialog>
|
|
1472
1771
|
</>
|
|
1473
1772
|
);
|
|
1474
1773
|
}
|
|
@@ -4,11 +4,5 @@ interface HomePageProps {
|
|
|
4
4
|
} | null;
|
|
5
5
|
onLogout: () => void;
|
|
6
6
|
}
|
|
7
|
-
interface HomePageProps {
|
|
8
|
-
user: {
|
|
9
|
-
email: string;
|
|
10
|
-
} | null;
|
|
11
|
-
onLogout: () => void;
|
|
12
|
-
}
|
|
13
7
|
export declare function HomePage({ user, onLogout }: HomePageProps): import("react/jsx-runtime").JSX.Element;
|
|
14
8
|
export {};
|
|
@@ -180,6 +180,28 @@ export interface XerticaAssistantProps {
|
|
|
180
180
|
*/
|
|
181
181
|
className?: string;
|
|
182
182
|
mobileFloating?: boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Função para gerar respostas customizadas
|
|
185
|
+
* @param message A mensagem do usuário
|
|
186
|
+
* @returns Promessa com a resposta ou a resposta diretamente
|
|
187
|
+
*/
|
|
188
|
+
responseGenerator?: (message: string) => Promise<string | Partial<Message>> | string | Partial<Message>;
|
|
189
|
+
/**
|
|
190
|
+
* Sugestões ricas adicionais (exibidas ao clicar em "Mais sugestões")
|
|
191
|
+
*/
|
|
192
|
+
richSuggestions?: Suggestion[];
|
|
193
|
+
/**
|
|
194
|
+
* Callback para ações de sugestão rica
|
|
195
|
+
*/
|
|
196
|
+
onRichAction?: (actionId: string, actionText: string) => void;
|
|
197
|
+
/**
|
|
198
|
+
* Callback para avaliação de mensagens
|
|
199
|
+
*/
|
|
200
|
+
onEvaluation?: (messageId: string, type: 'like' | 'dislike', reason?: string) => void;
|
|
201
|
+
/**
|
|
202
|
+
* Opções de feedback negativo (exibidas no dropdown de dislike)
|
|
203
|
+
*/
|
|
204
|
+
feedbackOptions?: string[];
|
|
183
205
|
}
|
|
184
206
|
/**
|
|
185
207
|
* XerticaAssistant - Assistente de IA completo com chat, histórico e favoritos
|
|
@@ -212,4 +234,4 @@ export interface XerticaAssistantProps {
|
|
|
212
234
|
* />
|
|
213
235
|
* ```
|
|
214
236
|
*/
|
|
215
|
-
export declare function XerticaAssistant({ mode, isExpanded: controlledIsExpanded, onToggle, defaultTab, showApiWarning, apiKey, onNavigateSettings, onNavigateFullPage, userName, initialMessages, savedConversations, suggestions: propSuggestions, onSendMessage, onFileAttach, isProcessing, width, height, className, mobileFloating, demoMode, customResponses }: XerticaAssistantProps): import("react/jsx-runtime").JSX.Element;
|
|
237
|
+
export declare function XerticaAssistant({ mode, isExpanded: controlledIsExpanded, onToggle, defaultTab, showApiWarning, apiKey, onNavigateSettings, onNavigateFullPage, userName, initialMessages, savedConversations, suggestions: propSuggestions, onSendMessage, onFileAttach, isProcessing, width, height, className, mobileFloating, demoMode, customResponses, responseGenerator, richSuggestions, onRichAction, onEvaluation, feedbackOptions }: XerticaAssistantProps): import("react/jsx-runtime").JSX.Element;
|