/**
* Reusable Loading Skeleton Components
* Provides consistent loading states across the application
*/
import React from "react";
export function CardSkeleton() {
return (
);
}
export function TableSkeleton({ rows = 5, columns = 4 }: { rows?: number; columns?: number }) {
return (
{/* Header */}
{Array.from({ length: columns }).map((_, i) => (
))}
{/* Rows */}
{Array.from({ length: rows }).map((_, rowIdx) => (
{Array.from({ length: columns }).map((_, colIdx) => (
))}
))}
);
}
export function ChartSkeleton() {
return (
);
}
export function ListSkeleton({ items = 5 }: { items?: number }) {
return (
{Array.from({ length: items }).map((_, i) => (
))}
);
}
export function StatCardSkeleton() {
return (
);
}
export function FormSkeleton() {
return (
{/* Form fields */}
{Array.from({ length: 4 }).map((_, i) => (
))}
{/* Buttons */}
);
}
export function PageSkeleton() {
return (
{/* Page header */}
{/* Stats Grid */}
{Array.from({ length: 4 }).map((_, i) => (
))}
{/* Main content */}
);
}
export function DashboardSkeleton() {
return (
{/* Header */}
{/* Stats */}
{Array.from({ length: 4 }).map((_, i) => (
))}
{/* Charts */}
{/* Recent activity */}
);
}
// Generic skeleton with custom content
export function Skeleton({
className = "",
variant = "default"
}: {
className?: string;
variant?: "default" | "circle" | "rectangle"
}) {
const baseClass = "bg-muted animate-pulse";
const variantClass = {
default: "rounded",
circle: "rounded-full",
rectangle: "rounded-lg",
}[variant];
return ;
}