174919da4e
T-032: User management admin panel - backend users router with CRUD, frontend UsersPage with modals T-033: Audit log viewer - backend audit router with filters/pagination, frontend AuditLogPage T-034: Global error handling - ErrorBoundary, LoadingSpinner, ErrorMessage, Toast components T-035: Backend tests - pytest setup with SQLite, tests for health/auth/techniques/tests T-036: Documentation - Updated README with testing section, created docs/API.md
37 lines
855 B
TypeScript
37 lines
855 B
TypeScript
import { Loader2 } from "lucide-react";
|
|
|
|
interface LoadingSpinnerProps {
|
|
size?: "sm" | "md" | "lg";
|
|
text?: string;
|
|
fullScreen?: boolean;
|
|
}
|
|
|
|
const sizeClasses = {
|
|
sm: "h-4 w-4",
|
|
md: "h-8 w-8",
|
|
lg: "h-12 w-12",
|
|
};
|
|
|
|
export default function LoadingSpinner({
|
|
size = "md",
|
|
text,
|
|
fullScreen = false,
|
|
}: LoadingSpinnerProps) {
|
|
const content = (
|
|
<div className="flex flex-col items-center justify-center gap-3">
|
|
<Loader2 className={`animate-spin text-cyan-400 ${sizeClasses[size]}`} />
|
|
{text && <p className="text-sm text-gray-400">{text}</p>}
|
|
</div>
|
|
);
|
|
|
|
if (fullScreen) {
|
|
return (
|
|
<div className="fixed inset-0 flex items-center justify-center bg-gray-950/80 backdrop-blur-sm z-50">
|
|
{content}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return <div className="flex h-64 items-center justify-center">{content}</div>;
|
|
}
|