'use client'; import { useState, useEffect } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Progress } from '@/components/ui/progress'; import { Badge } from '@/components/ui/badge'; import { apiClient, type JobInfo } from '@/lib/api'; import { Loader2, CheckCircle2, XCircle, Clock, AlertCircle, RefreshCw, Eye, Trash2 } from 'lucide-react'; import { cn } from '@/lib/utils'; interface ModelConversionProgressProps { requestId: string; modelName: string; quantizationType: string; onComplete?: () => void; onCancel?: () => void; } interface ConversionStatus { status: 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled'; progress: number; message: string; error?: string; createdAt: string; updatedAt: string; outputPath?: string; } export function ModelConversionProgress({ requestId, modelName, quantizationType, onComplete, onCancel }: ModelConversionProgressProps) { const [conversionStatus, setConversionStatus] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [polling, setPolling] = useState(true); useEffect(() => { if (!polling) return; const checkStatus = async () => { try { // Try to get job status from queue const queueStatus = await apiClient.getQueueStatus(); const job = queueStatus.jobs.find(j => j.request_id === requestId || j.id === requestId); if (job) { const status: ConversionStatus = { status: job.status as any, progress: job.progress || 0, message: job.message || 'Processing...', error: job.error, createdAt: job.created_at || new Date().toISOString(), updatedAt: job.updated_at || new Date().toISOString(), }; setConversionStatus(status); setError(null); // Stop polling if completed or failed if (job.status === 'completed') { setPolling(false); onComplete?.(); } else if (job.status === 'failed' || job.status === 'cancelled') { setPolling(false); setError(job.error || 'Conversion failed'); } } else { // Job not found in queue, might be completed or failed if (conversionStatus?.status !== 'completed') { setPolling(false); setError('Conversion job not found in queue'); } } } catch (err) { console.error('Failed to check conversion status:', err); setError('Failed to check status'); } finally { setLoading(false); } }; checkStatus(); // Poll every 2 seconds when active const interval = polling ? setInterval(checkStatus, 2000) : null; return () => { if (interval) clearInterval(interval); }; }, [requestId, polling, onComplete, conversionStatus?.status]); const getStatusIcon = () => { if (loading) return ; switch (conversionStatus?.status) { case 'completed': return ; case 'failed': return ; case 'processing': return ; case 'cancelled': return ; case 'pending': return ; default: return ; } }; const getStatusColor = () => { switch (conversionStatus?.status) { case 'completed': return 'text-green-600 dark:text-green-400'; case 'failed': return 'text-red-600 dark:text-red-400'; case 'processing': return 'text-blue-600 dark:text-blue-400'; case 'cancelled': return 'text-gray-600 dark:text-gray-400'; case 'pending': return 'text-yellow-600 dark:text-yellow-400'; default: return 'text-gray-600 dark:text-gray-400'; } }; const getStatusBadgeVariant = () => { switch (conversionStatus?.status) { case 'completed': return 'default'; case 'failed': return 'destructive'; case 'processing': return 'secondary'; case 'cancelled': return 'outline'; case 'pending': return 'outline'; default: return 'outline'; } }; if (error && !conversionStatus) { return (

Conversion Error

{error}

); } return (
{getStatusIcon()} Model Conversion Converting {modelName} to {quantizationType}
{conversionStatus?.status || 'Unknown'}
{conversionStatus?.message || 'Initializing...'} {conversionStatus ? Math.round(conversionStatus.progress * 100) : 0}%
Model:

{modelName}

Quantization:

{quantizationType}

{conversionStatus?.createdAt && (
Started:

{new Date(conversionStatus.createdAt).toLocaleTimeString()}

)} {conversionStatus?.updatedAt && (
Updated:

{new Date(conversionStatus.updatedAt).toLocaleTimeString()}

)}
{conversionStatus?.error && (

Error: {conversionStatus.error}

)} {conversionStatus?.status === 'completed' && (

Success! Model conversion completed successfully.

{conversionStatus.outputPath && (

Output: {conversionStatus.outputPath}

)}
)}
{polling && ( )} {!polling && conversionStatus?.status === 'processing' && ( )} {(conversionStatus?.status === 'failed' || conversionStatus?.status === 'cancelled') && ( )}
); }