Spaces:
Sleeping
Sleeping
File size: 3,316 Bytes
7017720 ea6c2a8 7017720 ea6c2a8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
import { useState, useEffect } from "react";
/**
* Enhanced loading component with visual feedback
*
* Features:
* - Progress indicator with percentage display
* - Animated loading spinner
* - Progress bar visualization
* - Contextual status messages
* - Animated ellipsis for active feedback
*
* @param progress - Current progress percentage (0-100)
* @param showDetails - Whether to show detailed status messages
*/
function Loading({ progress = 0, showDetails = false }: { progress?: number; showDetails?: boolean }) {
const [dots, setDots] = useState("");
// Animated dots for the loading text (provides visual feedback even when progress is unknown)
useEffect(() => {
const interval = setInterval(() => {
setDots(prev => (prev.length >= 3 ? "" : prev + "."));
}, 400);
return () => clearInterval(interval);
}, []);
// Get appropriate status message based on current progress
const getStatusMessage = () => {
if (progress < 25) return "Analyzing request...";
if (progress < 50) return "Generating content...";
if (progress < 75) return "Processing changes...";
if (progress < 100) return "Finalizing...";
return "Complete!";
};
return (
<div className="absolute left-0 top-0 h-full w-full flex flex-col items-center justify-center bg-gray-950/90 backdrop-blur-sm z-20">
<div className="relative">
{/* Progress circle with animated spin */}
<svg
className="size-16 animate-spin text-purple-400"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
{/* Progress percentage in center - only shown when progress is known */}
{progress > 0 && (
<div className="absolute inset-0 flex items-center justify-center">
<span className="text-sm font-bold text-white">{progress}%</span>
</div>
)}
</div>
<div className="mt-4 flex flex-col items-center">
{/* Main loading message with animated dots */}
<p className="text-lg font-bold text-purple-200 mb-1">AI is thinking{dots}</p>
{/* Horizontal progress bar - only shown when progress is known */}
{progress > 0 && (
<div className="w-48 h-1.5 bg-gray-700 rounded-full overflow-hidden mt-2">
<div
className="h-full bg-gradient-to-r from-purple-400 to-pink-500 transition-all duration-300 ease-out"
style={{ width: `${progress}%` }}
/>
</div>
)}
{/* Optional detailed status message - shows processing stage */}
{showDetails && (
<p className="mt-2 text-xs text-purple-300/80 max-w-xs text-center animate-pulse">
{getStatusMessage()}
</p>
)}
</div>
</div>
);
}
export default Loading;
|