'use client'; import React, { useState, useEffect } from 'react'; import { Activity, CheckCircle, Clock, XCircle, Zap, Filter } from 'lucide-react'; import { Spinner } from '@/components/ui/Spinner'; interface LogEntry { id: string; timestamp: string; campaign_name: string; rule_name: string; action: string; details: string; status: 'executed' | 'pending' | 'failed' | 'skipped'; } const statusConfig = { executed: { icon: , color: '#4ade80', bg: 'rgba(34,197,94,0.1)', label: 'Executado' }, pending: { icon: , color: '#fbbf24', bg: 'rgba(245,158,11,0.1)', label: 'Pendente' }, failed: { icon: , color: '#f87171', bg: 'rgba(239,68,68,0.1)', label: 'Falhou' }, skipped: { icon: , color: '#8888a0', bg: 'var(--overlay-05)', label: 'Pulado' }, }; function timeAgo(dateStr: string): string { const diff = Date.now() - new Date(dateStr).getTime(); const mins = Math.floor(diff / 60000); if (mins < 60) return `${mins}min atrás`; const hours = Math.floor(mins / 60); if (hours < 24) return `${hours}h atrás`; const days = Math.floor(hours / 24); return `${days}d atrás`; } export default function ActivityPage() { const [filter, setFilter] = useState('all'); const [allLogs, setAllLogs] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { (async () => { try { const res = await fetch('/api/engine/logs'); const data = await res.json(); if (data.success) setAllLogs(data.data || []); } catch { /* ignora */ } finally { setLoading(false); } })(); }, []); const logs = filter === 'all' ? allLogs : allLogs.filter((l) => l.status === filter); return (
{/* Header */}

Atividade

Ações executadas pelo agente de automação

{['all', 'executed', 'pending', 'skipped', 'failed'].map((f) => ( ))}
{/* Stats */}
{[ { label: 'Total', value: allLogs.length, color: 'var(--accent-soft-fg)' }, { label: 'Executados', value: allLogs.filter((l) => l.status === 'executed').length, color: '#4ade80' }, { label: 'Pendentes', value: allLogs.filter((l) => l.status === 'pending').length, color: '#fbbf24' }, { label: 'Pulados', value: allLogs.filter((l) => l.status === 'skipped').length, color: '#8888a0' }, ].map((s) => (

{s.value}

{s.label}

))}
{/* Timeline */}

Timeline

{loading ? (
) : logs.length === 0 ? (

Nenhuma atividade ainda. Quando o engine agir ou recomendar algo, aparece aqui.

) : ( logs.map((log) => { const sc = statusConfig[log.status]; return (
{/* Timeline dot */}
{/* Content */}

{log.campaign_name}

{sc.icon} {sc.label}

Regra: {log.rule_name}

{log.details}

{/* Time */} {timeAgo(log.timestamp)}
); }) )}
); }