"use client"; /** * 统一 API 状态组件 * - LoadingState: 骨架屏加载状态 * - ErrorState: 错误展示 + 重试按钮 * - EmptyState: 空数据状态 */ import { AlertCircle, RefreshCw, Inbox } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; // ── LoadingState ───────────────────────────────────────────────────────────── export interface LoadingStateProps { /** 骨架行数(默认 3) */ rows?: number; /** 是否展示卡片网格布局(默认 false,展示列表) */ grid?: boolean; /** 网格列数(grid=true 时生效,默认 3) */ cols?: 2 | 3 | 4; /** 自定义高度类名(如 "h-24") */ rowHeight?: string; } export function LoadingState({ rows = 3, grid = false, cols = 3, rowHeight = "h-24", }: LoadingStateProps) { const colClass = { 2: "md:grid-cols-2", 3: "md:grid-cols-2 lg:grid-cols-3", 4: "md:grid-cols-2 lg:grid-cols-4", }[cols]; if (grid) { return (
{Array.from({ length: rows }).map((_, i) => ( ))}
); } return (
{Array.from({ length: rows }).map((_, i) => ( ))}
); } // ── ErrorState ─────────────────────────────────────────────────────────────── export interface ErrorStateProps { /** 错误对象或错误消息字符串 */ error: Error | string | null | undefined; /** 点击重试的回调 */ onRetry?: () => void; /** 重试按钮文字(默认"重试") */ retryLabel?: string; /** 标题(默认"数据加载失败") */ title?: string; } export function ErrorState({ error, onRetry, retryLabel = "重试", title = "数据加载失败", }: ErrorStateProps) { const message = error instanceof Error ? error.message : typeof error === "string" ? error : "发生未知错误,请稍后重试"; return (

{title}

{message}

{onRetry && ( )}
); } // ── EmptyState ─────────────────────────────────────────────────────────────── export interface EmptyStateProps { /** 主提示文字 */ message?: string; /** 次级说明文字 */ description?: string; /** 操作按钮(可选) */ action?: React.ReactNode; /** 自定义图标 */ icon?: React.ReactNode; } export function EmptyState({ message = "暂无数据", description, action, icon, }: EmptyStateProps) { return (
{icon ?? }

{message}

{description && (

{description}

)} {action &&
{action}
}
); }