import React, { useCallback, useEffect, useState, useMemo } from 'react'; import { useSettings } from '~/lib/hooks/useSettings'; import { toast } from 'react-toastify'; import { Switch } from '~/components/ui/Switch'; import { logStore, type LogEntry } from '~/lib/stores/logs'; import { useStore } from '@nanostores/react'; import { classNames } from '~/utils/classNames'; export default function EventLogsTab() { const {} = useSettings(); const showLogs = useStore(logStore.showLogs); const [logLevel, setLogLevel] = useState('info'); const [autoScroll, setAutoScroll] = useState(true); const [searchQuery, setSearchQuery] = useState(''); const [, forceUpdate] = useState({}); const filteredLogs = useMemo(() => { const logs = logStore.getLogs(); return logs.filter((log) => { const matchesLevel = !logLevel || log.level === logLevel || logLevel === 'all'; const matchesSearch = !searchQuery || log.message?.toLowerCase().includes(searchQuery.toLowerCase()) || JSON.stringify(log.details)?.toLowerCase()?.includes(searchQuery?.toLowerCase()); return matchesLevel && matchesSearch; }); }, [logLevel, searchQuery]); // Effect to initialize showLogs useEffect(() => { logStore.showLogs.set(true); }, []); useEffect(() => { // System info logs logStore.logSystem('Application initialized', { version: process.env.NEXT_PUBLIC_APP_VERSION, environment: process.env.NODE_ENV, }); // Debug logs for system state logStore.logDebug('System configuration loaded', { runtime: 'Next.js', features: ['AI Chat', 'Event Logging'], }); // Warning logs for potential issues logStore.logWarning('Resource usage threshold approaching', { memoryUsage: '75%', cpuLoad: '60%', }); // Error logs with detailed context logStore.logError('API connection failed', new Error('Connection timeout'), { endpoint: '/api/chat', retryCount: 3, lastAttempt: new Date().toISOString(), }); }, []); useEffect(() => { const container = document.querySelector('.logs-container'); if (container && autoScroll) { container.scrollTop = container.scrollHeight; } }, [filteredLogs, autoScroll]); const handleClearLogs = useCallback(() => { if (confirm('Are you sure you want to clear all logs?')) { logStore.clearLogs(); toast.success('Logs cleared successfully'); forceUpdate({}); // Force a re-render after clearing logs } }, []); const handleExportLogs = useCallback(() => { try { const logText = logStore .getLogs() .map( (log) => `[${log.level.toUpperCase()}] ${log.timestamp} - ${log.message}${ log.details ? '\nDetails: ' + JSON.stringify(log.details, null, 2) : '' }`, ) .join('\n\n'); const blob = new Blob([logText], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `event-logs-${new Date().toISOString()}.txt`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); toast.success('Logs exported successfully'); } catch (error) { toast.error('Failed to export logs'); console.error('Export error:', error); } }, []); const getLevelColor = (level: LogEntry['level']) => { switch (level) { case 'info': return 'text-blue-500'; case 'warning': return 'text-yellow-500'; case 'error': return 'text-red-500'; case 'debug': return 'text-gray-500'; default: return 'text-bolt-elements-textPrimary'; } }; return (
{/* Title and Toggles Row */}

Event Logs

Show Actions logStore.showLogs.set(checked)} />
Auto-scroll
{/* Controls Row */}
setSearchQuery(e.target.value)} className="w-full bg-white dark:bg-bolt-elements-background-depth-4 relative px-2 py-1.5 rounded-md focus:outline-none placeholder-bolt-elements-textTertiary text-bolt-elements-textPrimary dark:text-bolt-elements-textPrimary border border-bolt-elements-borderColor" />
{showLogs && (
)}
{filteredLogs.length === 0 ? (
No logs found
) : ( filteredLogs.map((log, index) => (
[{log.level.toUpperCase()}] {new Date(log.timestamp).toLocaleString()} {log.message}
{log.details && (
                  {JSON.stringify(log.details, null, 2)}
                
)}
)) )}
); }