feat(phase-9): implement MVP polishing and closure
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
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
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>;
|
||||
}
|
||||
Reference in New Issue
Block a user