import { CheckCircle, Upload, AlertCircle, Loader2 } from 'lucide-react'; import { Card, CardContent } from '@/components/ui/card'; import type { UploadTask } from '@/types'; interface UploadProgressProps { tasks: UploadTask[]; } export function UploadProgress({ tasks }: UploadProgressProps) { if (tasks.length === 0) return null; const completedCount = tasks.filter(t => t.status === 'completed').length; const errorCount = tasks.filter(t => t.status === 'error').length; const totalCount = tasks.length; const processedCount = completedCount + errorCount; const allDone = processedCount === totalCount; // Find currently uploading file const currentFile = tasks.find(t => t.status === 'uploading'); const currentFileName = currentFile?.key.split('/').pop() || currentFile?.key || 'Processing...'; // File-based progress plus contribution from current upload const baseProgress = (processedCount / totalCount) * 100; const currentFileContribution = currentFile ? (currentFile.progress / 100) * (1 / totalCount) * 100 : 0; const overallProgress = Math.min(baseProgress + currentFileContribution, 100); return (
{/* Header with icon and status */}
0 ? 'bg-yellow-500/10 dark:bg-yellow-500/20' : 'bg-primary/10 dark:bg-primary/20' }`}> {allDone ? ( ) : errorCount > 0 ? ( ) : ( )}
{allDone ? 'Upload Complete' : 'Uploading Files'}
{processedCount} of {totalCount} files
{Math.round(overallProgress)}%
{/* Progress bar with gradient */}
{!allDone && currentFile && (
{currentFileName}
)}
{/* Animated shimmer effect */} {!allDone && overallProgress > 0 && (
)}
{/* Error indicator with icon */} {errorCount > 0 && (
{errorCount} file{errorCount > 1 ? 's' : ''} failed to upload
)} {/* Success message */} {allDone && errorCount === 0 && (
All files uploaded successfully
)}
); }