Files
aerbim-ht-monitor/frontend/components/ui/LoadingSpinner.tsx

72 lines
1.9 KiB
TypeScript

'use client'
import React from 'react'
interface LoadingSpinnerProps {
progress?: number // 0-100
size?: number // diameter in pixels
strokeWidth?: number
className?: string
}
const LoadingSpinner: React.FC<LoadingSpinnerProps> = ({
progress = 0,
size = 120,
strokeWidth = 8,
className = ''
}) => {
const radius = (size - strokeWidth) / 2
const circumference = radius * 2 * Math.PI
const strokeDasharray = circumference
const strokeDashoffset = circumference - (progress / 100) * circumference
return (
<div className={`flex flex-col items-center justify-center ${className}`}>
<div className="relative" style={{ width: size, height: size }}>
{/* Background circle */}
<svg
className="transform -rotate-90"
width={size}
height={size}
viewBox={`0 0 ${size} ${size}`}
>
<circle
cx={size / 2}
cy={size / 2}
r={radius}
stroke="rgba(255, 255, 255, 0.1)"
strokeWidth={strokeWidth}
fill="transparent"
/>
{/* Progress circle */}
<circle
cx={size / 2}
cy={size / 2}
r={radius}
stroke="#389ee8"
strokeWidth={strokeWidth}
fill="transparent"
strokeDasharray={strokeDasharray}
strokeDashoffset={strokeDashoffset}
strokeLinecap="round"
className="transition-all duration-300 ease-out"
/>
</svg>
{/* Percentage text */}
<div className="absolute inset-0 flex items-center justify-center">
<span className="text-white text-xl font-semibold">
{Math.round(progress)}%
</span>
</div>
</div>
{/* Loading text */}
<div className="mt-4 text-white text-base font-medium">
Loading Model...
</div>
</div>
)
}
export default LoadingSpinner