"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}
}
);
}