/** * 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
; }