| import React from "react"; | |
| import { cn } from "@/lib/utils/cn"; | |
| interface LoadingSpinnerProps { | |
| size?: "sm" | "md" | "lg"; | |
| className?: string; | |
| } | |
| export const LoadingSpinner: React.FC<LoadingSpinnerProps> = ({ | |
| size = "md", | |
| className, | |
| }) => { | |
| const sizes = { | |
| sm: "h-4 w-4", | |
| md: "h-8 w-8", | |
| lg: "h-12 w-12", | |
| }; | |
| return ( | |
| <div className={cn("flex items-center justify-center relative", className)}> | |
| {/* Outer glow */} | |
| <div className={cn("absolute rounded-full bg-gradient-to-r from-blue-500 to-cyan-500 opacity-20 animate-ping", sizes[size])}></div> | |
| {/* Main spinner */} | |
| <svg | |
| className={cn("animate-spin relative z-10", sizes[size])} | |
| xmlns="http://www.w3.org/2000/svg" | |
| fill="none" | |
| viewBox="0 0 24 24" | |
| > | |
| <defs> | |
| <linearGradient id="spinner-gradient" x1="0%" y1="0%" x2="100%" y2="100%"> | |
| <stop offset="0%" stopColor="#3b82f6" /> | |
| <stop offset="50%" stopColor="#06b6d4" /> | |
| <stop offset="100%" stopColor="#ec4899" /> | |
| </linearGradient> | |
| </defs> | |
| <circle | |
| className="opacity-25" | |
| cx="12" | |
| cy="12" | |
| r="10" | |
| stroke="currentColor" | |
| strokeWidth="4" | |
| ></circle> | |
| <path | |
| className="opacity-75" | |
| fill="url(#spinner-gradient)" | |
| 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> | |
| </div> | |
| ); | |
| }; | |