'use client'; import { useState, useEffect, useRef } from 'react'; import type { LogEntry, EventCategory } from '../types/realtime-events'; interface ActivityLogPanelProps { logs: LogEntry[]; onClear: () => void; } export default function ActivityLogPanel({ logs, onClear }: ActivityLogPanelProps) { const [isOpen, setIsOpen] = useState(false); const [unreadCount, setUnreadCount] = useState(0); const logContainerRef = useRef(null); const prevLogsLengthRef = useRef(0); // Auto-scroll to bottom when new logs arrive useEffect(() => { if (logContainerRef.current && isOpen) { logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight; } }, [logs, isOpen]); // Track unread count useEffect(() => { if (!isOpen && logs.length > prevLogsLengthRef.current) { const newLogs = logs.length - prevLogsLengthRef.current; setUnreadCount(prev => prev + newLogs); } prevLogsLengthRef.current = logs.length; }, [logs, isOpen]); // Reset unread count when opening useEffect(() => { if (isOpen) { setUnreadCount(0); } }, [isOpen]); function getCategoryColor(category: EventCategory): string { switch (category) { case 'connection': return 'bg-blue-100 text-blue-800 border-blue-200'; case 'speech': return 'bg-green-100 text-green-800 border-green-200'; case 'transcription': return 'bg-cyan-100 text-cyan-800 border-cyan-200'; case 'tool_call': return 'bg-purple-100 text-purple-800 border-purple-200'; case 'response': return 'bg-yellow-100 text-yellow-800 border-yellow-200'; case 'error': return 'bg-red-100 text-red-800 border-red-200'; case 'buffer': return 'bg-gray-100 text-gray-800 border-gray-200'; case 'audio': return 'bg-indigo-100 text-indigo-800 border-indigo-200'; default: return 'bg-gray-100 text-gray-800 border-gray-200'; } } function formatTime(timestamp: number): string { const date = new Date(timestamp); const hours = date.getHours().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0'); const seconds = date.getSeconds().toString().padStart(2, '0'); const ms = date.getMilliseconds().toString().padStart(3, '0'); return `${hours}:${minutes}:${seconds}.${ms}`; } function LogEntryItem({ entry }: { entry: LogEntry }) { const [isExpanded, setIsExpanded] = useState(false); return (
{formatTime(entry.timestamp)} {entry.category.toUpperCase()}
{entry.summary || entry.eventType}
{isExpanded && (
            {JSON.stringify(entry.event, null, 2)}
          
)}
); } return ( <> {/* Toggle Button */} {/* Panel */}
{/* Header */}

Activity Log

{/* Log Container */}
{logs.length === 0 ? (
No events yet. Connect to start logging.
) : ( logs.map(entry => ) )}
); }