evolution-api/dashboard/components/MessageTimeline.tsx
Claude 97e3930033
feat: adiciona painel interativo com chat e IA para análise de mensagens
- Dashboard completo com métricas em tempo real
- Chat interativo com IA para consultas em linguagem natural
- Análise de sentimento das mensagens
- Gráficos interativos (mensagens por dia, sentimentos)
- Filtros avançados por instância e data
- Top contatos e timeline de mensagens
- API routes para stats, mensagens, sentimento e chat
- Integração com PostgreSQL via Prisma
- Interface moderna com Next.js 14, TypeScript e Tailwind CSS
- Documentação completa com README e QUICKSTART
2025-11-14 03:16:46 +00:00

119 lines
4.0 KiB
TypeScript

'use client';
import { Clock, MessageCircle } from 'lucide-react';
import { formatDistanceToNow } from 'date-fns';
import { ptBR } from 'date-fns/locale';
export default function MessageTimeline() {
// Dados de exemplo - substituir por dados reais da API
const recentMessages = [
{
id: 1,
contact: 'João Silva',
message: 'Olá, gostaria de saber mais sobre o produto...',
time: new Date(Date.now() - 5 * 60 * 1000),
sentiment: 'positive',
type: 'received'
},
{
id: 2,
contact: 'Maria Santos',
message: 'Obrigada pelo atendimento!',
time: new Date(Date.now() - 15 * 60 * 1000),
sentiment: 'very_positive',
type: 'received'
},
{
id: 3,
contact: 'Pedro Oliveira',
message: 'Ainda não recebi meu pedido',
time: new Date(Date.now() - 30 * 60 * 1000),
sentiment: 'negative',
type: 'received'
},
{
id: 4,
contact: 'Ana Costa',
message: 'Qual o prazo de entrega?',
time: new Date(Date.now() - 45 * 60 * 1000),
sentiment: 'neutral',
type: 'received'
},
{
id: 5,
contact: 'Carlos Souza',
message: 'Produto excelente, recomendo!',
time: new Date(Date.now() - 60 * 60 * 1000),
sentiment: 'very_positive',
type: 'received'
},
];
const getSentimentColor = (sentiment: string) => {
const colors: { [key: string]: string } = {
very_positive: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
positive: 'bg-green-50 text-green-700 dark:bg-green-800 dark:text-green-300',
neutral: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200',
negative: 'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200',
very_negative: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
};
return colors[sentiment] || colors.neutral;
};
const getSentimentLabel = (sentiment: string) => {
const labels: { [key: string]: string } = {
very_positive: 'Muito Positivo',
positive: 'Positivo',
neutral: 'Neutro',
negative: 'Negativo',
very_negative: 'Muito Negativo',
};
return labels[sentiment] || 'Neutro';
};
return (
<div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm p-6 border border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between mb-6">
<div className="flex items-center space-x-2">
<Clock className="w-5 h-5 text-primary-500" />
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
Mensagens Recentes
</h3>
</div>
<button className="text-sm text-primary-500 hover:text-primary-600 font-medium">
Ver todas
</button>
</div>
<div className="space-y-4">
{recentMessages.map((msg) => (
<div
key={msg.id}
className="flex items-start space-x-3 p-3 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
>
<div className="flex-shrink-0 mt-1">
<MessageCircle className="w-5 h-5 text-gray-400" />
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center justify-between mb-1">
<p className="text-sm font-medium text-gray-900 dark:text-white">
{msg.contact}
</p>
<span className="text-xs text-gray-500 dark:text-gray-400">
{formatDistanceToNow(msg.time, { addSuffix: true, locale: ptBR })}
</span>
</div>
<p className="text-sm text-gray-600 dark:text-gray-300 line-clamp-2 mb-2">
{msg.message}
</p>
<span className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${getSentimentColor(msg.sentiment)}`}>
{getSentimentLabel(msg.sentiment)}
</span>
</div>
</div>
))}
</div>
</div>
);
}