'use client' import { useState, useEffect, useRef } from 'react' import { cn } from '@/lib/utils' import { agentMsgs } from '@/lib/mock-data' import { Bot, ChevronDown, ChevronUp, Zap } from 'lucide-react' interface LiveEvent { ingestionId: string; wallet: string; eventName: string risk?: string; score?: number; firedAt: string; source: string } const EVENT_EMOJI: Record = { churn_risk_high: '🚨', churn_risk_medium: '⚠️', comeback_detected: '🔥', streak_maintained: '⚡', volume_milestone: '🏆', inactivity_detected: '💤', referral_from_saved: '🤝', } function liveEventToMsg(e: LiveEvent): string { const emoji = EVENT_EMOJI[e.eventName] || '📡' const short = `${e.wallet.slice(0, 6)}...${e.wallet.slice(-4)}` const label = e.eventName.replace(/_/g, ' ') const score = e.score !== undefined ? ` (score=${e.score})` : '' return `${emoji} LIVE: ${label} → ${short}${score} [${e.ingestionId.slice(0, 8)}]` } export function AgentFeed() { const [msgs, setMsgs] = useState<{ text: string; time: string; live?: boolean }[]>([]) const [open, setOpen] = useState(true) const [liveCount, setLiveCount] = useState(0) const seenIds = useRef(new Set()) // Seed mock messages useEffect(() => { const init = agentMsgs.slice(0, 5).map((t, i) => ({ text: t, time: new Date(Date.now() - i * 120000).toLocaleTimeString('en-US', { hour12: false }), })) setMsgs(init) let c = 5 const iv = setInterval(() => { const t = agentMsgs[c++ % agentMsgs.length] setMsgs(p => [{ text: t, time: new Date().toLocaleTimeString('en-US', { hour12: false }) }, ...p].slice(0, 30)) }, 4000) return () => clearInterval(iv) }, []) // Poll real events and inject at top useEffect(() => { const poll = async () => { try { const res = await fetch('/api/torque/events/recent?limit=10') if (!res.ok) return const data = await res.json() const events: LiveEvent[] = data.events || [] const newEvents = events.filter(e => !seenIds.current.has(e.ingestionId)) if (newEvents.length === 0) return newEvents.forEach(e => seenIds.current.add(e.ingestionId)) const now = new Date().toLocaleTimeString('en-US', { hour12: false }) const liveLines = newEvents.map(e => ({ text: liveEventToMsg(e), time: now, live: true })) setMsgs(p => [...liveLines, ...p].slice(0, 30)) setLiveCount(data.total || 0) } catch {} } poll() const iv = setInterval(poll, 4000) return () => clearInterval(iv) }, []) return (
{open && (
{msgs.map((m, i) => (
{m.time} {m.text} {m.live && LIVE}
))}
)}
) }