|
|
import React from "react"; |
|
|
import { cn } from "@/lib/utils/cn"; |
|
|
|
|
|
interface ProgressBarProps { |
|
|
progress: number; |
|
|
label?: string; |
|
|
showPercentage?: boolean; |
|
|
className?: string; |
|
|
} |
|
|
|
|
|
export const ProgressBar: React.FC<ProgressBarProps> = ({ |
|
|
progress, |
|
|
label, |
|
|
showPercentage = true, |
|
|
className, |
|
|
}) => { |
|
|
const clampedProgress = Math.min(100, Math.max(0, progress)); |
|
|
|
|
|
return ( |
|
|
<div className={cn("w-full", className)}> |
|
|
{label && ( |
|
|
<div className="flex justify-between items-center mb-3"> |
|
|
<span className="text-sm font-semibold text-gray-700">{label}</span> |
|
|
{showPercentage && ( |
|
|
<span className="text-sm font-bold bg-gradient-to-r from-blue-600 to-cyan-600 bg-clip-text text-transparent"> |
|
|
{Math.round(clampedProgress)}% |
|
|
</span> |
|
|
)} |
|
|
</div> |
|
|
)} |
|
|
<div className="relative w-full bg-gray-200/50 rounded-full h-3 overflow-hidden backdrop-blur-sm shadow-inner"> |
|
|
<div |
|
|
className="h-full rounded-full bg-gradient-to-r from-blue-500 via-cyan-500 via-pink-500 to-purple-500 transition-all duration-700 ease-out relative overflow-hidden" |
|
|
style={{ |
|
|
width: `${clampedProgress}%`, |
|
|
backgroundSize: "200% 100%", |
|
|
animation: clampedProgress > 0 && clampedProgress < 100 ? "gradient-shift 3s ease infinite" : "none" |
|
|
}} |
|
|
> |
|
|
{/* Animated shimmer effect */} |
|
|
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/40 to-transparent animate-shimmer"></div> |
|
|
|
|
|
{/* Glowing effect at the end */} |
|
|
{clampedProgress > 0 && ( |
|
|
<div |
|
|
className="absolute right-0 top-0 bottom-0 w-8 bg-gradient-to-l from-white/50 to-transparent blur-sm" |
|
|
style={{ opacity: clampedProgress < 100 ? 1 : 0 }} |
|
|
/> |
|
|
)} |
|
|
</div> |
|
|
|
|
|
{/* Pulse effect on the progress bar */} |
|
|
{clampedProgress > 0 && clampedProgress < 100 && ( |
|
|
<div |
|
|
className="absolute top-1/2 -translate-y-1/2 h-5 w-5 rounded-full bg-white shadow-lg transform transition-all duration-300" |
|
|
style={{ |
|
|
left: `calc(${clampedProgress}% - 10px)`, |
|
|
boxShadow: "0 0 10px rgba(59, 130, 246, 0.5), 0 0 20px rgba(6, 182, 212, 0.3)" |
|
|
}} |
|
|
/> |
|
|
)} |
|
|
</div> |
|
|
</div> |
|
|
); |
|
|
}; |
|
|
|