'use client'; import { useMemo } from 'react'; import { LineChart, Line, AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, ReferenceLine, } from 'recharts'; import { Activity, TrendingUp, HardDrive, Scroll } from 'lucide-react'; /** * Represents a single metrics sample collected during job execution */ export interface MetricsSample { timestamp_ms: number; reviews_extracted: number; scroll_count: number; memory_mb: number; extraction_rate: number; // reviews per second } interface MetricsDashboardProps { metricsHistory: MetricsSample[]; currentMetrics?: MetricsSample; isStreaming: boolean; } /** * Formats a timestamp (in ms) to a relative time string * e.g., "0s", "30s", "1m", "1m 30s", etc. */ function formatRelativeTime(timestampMs: number, startMs: number): string { const elapsedMs = timestampMs - startMs; const totalSeconds = Math.floor(elapsedMs / 1000); if (totalSeconds < 60) { return `${totalSeconds}s`; } const minutes = Math.floor(totalSeconds / 60); const seconds = totalSeconds % 60; if (seconds === 0) { return `${minutes}m`; } return `${minutes}m ${seconds}s`; } /** * MetricsDashboard displays real-time metrics during job execution * with charts for extraction rate, cumulative reviews, and memory usage. */ export default function MetricsDashboard({ metricsHistory, currentMetrics, isStreaming, }: MetricsDashboardProps) { // Determine the starting timestamp for relative time calculations const startTimestamp = useMemo(() => { if (metricsHistory.length > 0) { return metricsHistory[0].timestamp_ms; } return currentMetrics?.timestamp_ms ?? Date.now(); }, [metricsHistory, currentMetrics]); // Transform metrics history for charts with relative time labels const chartData = useMemo(() => { return metricsHistory.map((sample) => ({ ...sample, time: formatRelativeTime(sample.timestamp_ms, startTimestamp), timeMs: sample.timestamp_ms - startTimestamp, })); }, [metricsHistory, startTimestamp]); // Get the latest metrics (either current or last from history) const latestMetrics = currentMetrics ?? metricsHistory[metricsHistory.length - 1]; // Memory warning threshold const MEMORY_WARNING_MB = 1500; // Check if memory is above warning threshold const isMemoryWarning = latestMetrics && latestMetrics.memory_mb >= MEMORY_WARNING_MB; // Custom tooltip style const tooltipStyle = { backgroundColor: '#1f2937', border: '1px solid #374151', borderRadius: '8px', padding: '8px 12px', }; return (