import { AlertTriangle, Loader2 } from "lucide-react"; import { GlassPanel, Skeleton, Spinner } from "@/components/primitives"; import { cn } from "@/lib/utils"; /** A panel-shaped loading placeholder. */ export function SkeletonPanel({ rows = 3, className, }: { rows?: number; className?: string; }) { return (
{Array.from({ length: rows }).map((_, i) => (
))}
); } /** A 2×2 (or 4-col) grid of metric-tile placeholders. */ export function SkeletonMetricRow({ cols = 4 }: { cols?: number }) { return (
{Array.from({ length: cols }).map((_, i) => (
))}
); } /** A stacked list of row placeholders (message/moderation/queue style). */ export function SkeletonRows({ rows = 6, className, }: { rows?: number; className?: string; }) { return (
{Array.from({ length: rows }).map((_, i) => (
))}
); } /** Hero block placeholder (dashboard / media "now playing"). */ export function SkeletonHero({ className }: { className?: string }) { return (
); } export function EmptyState({ title = "Nothing here yet", description, icon, className, }: { title?: string; description?: string; icon?: React.ReactNode; className?: string; }) { return (
{icon && ( {icon} )}
{title}
{description && (
{description}
)}
); } export function ErrorState({ title = "Couldn't load", error, onRetry, }: { title?: string; error?: unknown; onRetry?: () => void; }) { const msg = error instanceof Error ? error.message : String(error ?? ""); return (
{title}
{msg && (
{msg}
)} {onRetry && ( )}
); } export function LoadingState({ label = "Syncing" }: { label?: string }) { return (
{label}
); } export { Loader2 };