KingNish's picture
Upload 29 files
3baa9da verified
'use client';
interface ProgressProps {
text?: string;
percentage?: number;
loaded?: number;
total?: number;
done?: boolean;
}
// Helper to format bytes to KB/MB/GB
function formatBytes(bytes?: number): string {
if (bytes === undefined || bytes === null) return '';
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
}
export default function Progress({ text, percentage, loaded, total, done }: ProgressProps) {
// Ensure percentage is always a number between 0 and 100
// percentage = Math.min(100, Math.max(0,
// percentage ?? (loaded && total ? (loaded / total) * 100 : 0)
// ));
return (
<div className="w-full max-w-4xl mx-auto">
{text && (
<div className="flex justify-between text-sm text-gray-600 mb-1 items-center">
<span className="truncate max-w-[70%]">{text}</span>
{done ? (
<span className="flex items-center text-green-600 font-semibold whitespace-nowrap">
<svg className="w-5 h-5 mr-1 text-green-500" fill="none" stroke="currentColor" strokeWidth="3" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
</svg>
Download completed
</span>
) : (
<span className="whitespace-nowrap">
{loaded !== undefined && total !== undefined && percentage !== undefined && total > 0
? `${formatBytes(loaded)} / ${formatBytes(total)} (${percentage.toFixed(1)}%)`
: `${percentage}%`}
</span>
)}
</div>
)}
<div className="w-full bg-gray-200 rounded-full h-3">
<div
className={`${done
? 'bg-green-500'
: 'bg-gradient-to-r from-blue-400 to-blue-600'} h-3 rounded-full transition-all duration-300`}
style={{ width: `${percentage}%` }}
></div>
</div>
</div>
);
}