import { useEffect, useRef, useState } from 'react'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; interface RealTimeStatsDashboardProps { isOpen: boolean; onOpenChange: (open: boolean) => void; synthesizerStartTime: number | null; isSynthesizing: boolean; currentVoiceName?: string; enrolledVoiceCount?: number; } export default function RealTimeStatsDashboard({ isOpen, onOpenChange, synthesizerStartTime, isSynthesizing, currentVoiceName = 'Current Voice', enrolledVoiceCount = 5 }: RealTimeStatsDashboardProps) { const [elapsedSeconds, setElapsedSeconds] = useState(0); const animationFrameRef = useRef(); // Update elapsed time in real-time useEffect(() => { const updateElapsed = () => { if (synthesizerStartTime && isSynthesizing) { const elapsed = (Date.now() - synthesizerStartTime) / 1000; setElapsedSeconds(elapsed); animationFrameRef.current = requestAnimationFrame(updateElapsed); } else { setElapsedSeconds(0); } }; if (isOpen && isSynthesizing) { animationFrameRef.current = requestAnimationFrame(updateElapsed); } return () => { if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); } }; }, [isOpen, isSynthesizing, synthesizerStartTime]); // Stage timing configuration const stages = [ { name: 'Speaker Encoder', duration: 3, startTime: 0, color: '#ff6b6b' }, { name: 'Tacotron2 Synthesizer', duration: 45, startTime: 3, color: '#4ecdc4' }, { name: 'WaveRNN Vocoder', duration: 12, startTime: 48, color: '#45b7d1' } ]; // Calculate metrics based on actual elapsed time const getStageProgress = (stage: typeof stages[0]) => { if (elapsedSeconds < stage.startTime) { return 0; } else if (elapsedSeconds >= stage.startTime && elapsedSeconds < stage.startTime + stage.duration) { const stageElapsed = elapsedSeconds - stage.startTime; return Math.min(99, (stageElapsed / stage.duration) * 100); } else { return 100; } }; // Simulated CPU and memory (would come from backend in production) const cpuUsage = Math.min(95, Math.max(10, 50 + Math.sin(elapsedSeconds) * 30)); const memoryUsage = Math.min(90, Math.max(20, 60 + Math.cos(elapsedSeconds * 0.5) * 20)); return ( Real-Time Synthesis Dashboard Synthesis progress and system metrics
{/* Metrics Grid */}
{stages.map((stage) => { const progress = getStageProgress(stage); return ( {stage.name}
Progress {Math.round(progress)}%
{progress < 100 ? `${stage.startTime}s - ${stage.startTime + stage.duration}s` : 'Completed'}
); })}
{/* System Metrics */}
CPU Usage
Current {Math.round(cpuUsage)}%
Memory Usage
Current {Math.round(memoryUsage)}%
{/* Elapsed Time Display */}
Total Elapsed Time {elapsedSeconds.toFixed(1)}s
{isSynthesizing && (
● Synthesis in progress...
)}
); }