'use client'; import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { Search, Clock, AlertCircle, ExternalLink } from 'lucide-react'; import { api } from '@/lib/api'; import { TraceTimeline } from '@/components/traces/TraceTimeline'; import { formatDuration, formatTime } from '@/lib/utils'; interface Trace { trace_id: string; services: string[]; start_time: string; duration_ns: number; span_count: number; has_error: boolean; root_span?: { operation: string; service: string; }; } export default function TracesPage() { const [service, setService] = useState(''); const [operation, setOperation] = useState(''); const [minDuration, setMinDuration] = useState(''); const [onlyErrors, setOnlyErrors] = useState(false); const [selectedTrace, setSelectedTrace] = useState(null); const { data: traces, isLoading, refetch } = useQuery({ queryKey: ['traces', service, operation, minDuration, onlyErrors], queryFn: () => api.get('/api/v1/traces', { service, operation, min_duration_ms: minDuration, error: onlyErrors ? 'true' : '', from: new Date(Date.now() - 3600000).toISOString(), }), }); const { data: traceDetail } = useQuery({ queryKey: ['trace', selectedTrace], queryFn: () => api.get(`/api/v1/traces/${selectedTrace}`), enabled: !!selectedTrace, }); return (

Traces

{/* Filters */}
setService(e.target.value)} placeholder="All services" className="w-full px-3 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-indigo-500" />
setOperation(e.target.value)} placeholder="All operations" className="w-full px-3 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-indigo-500" />
setMinDuration(e.target.value)} placeholder="ms" className="w-full px-3 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-indigo-500" />
{/* Trace List */}

{isLoading ? 'Loading...' : `${traces?.traces?.length ?? 0} traces`}

{traces?.traces?.map((trace: Trace) => (
setSelectedTrace(trace.trace_id)} className={`p-4 bg-gray-900/50 rounded-lg border cursor-pointer transition-colors ${ selectedTrace === trace.trace_id ? 'border-indigo-500' : 'border-gray-800 hover:border-gray-700' }`} >
{trace.has_error && ( )} {trace.root_span?.operation || trace.trace_id.slice(0, 16)}
{trace.services?.slice(0, 3).map((svc) => ( {svc} ))} {(trace.services?.length ?? 0) > 3 && ( +{trace.services.length - 3} more )}
{formatDuration(trace.duration_ns)}
{trace.span_count} spans
{formatTime(trace.start_time)}
))} {!isLoading && (!traces?.traces || traces.traces.length === 0) && (
No traces found
)}
{/* Trace Detail */}

Trace Timeline

{selectedTrace && traceDetail ? ( ) : (
Select a trace to view timeline
)}
); }