"use client"
import { type ReactNode, Suspense } from "react"
import { AlertCircle } from "lucide-react"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { Card, CardContent, CardHeader } from "@/shared/components/ui/card"
import { Skeleton } from "@/shared/components/ui/skeleton"
import { useTranslations } from "next-intl"
import { SectionErrorBoundary } from "@/shared/components/section-error-boundary"
/**
* 分区骨架屏变体
*
* 不同数据区块使用不同骨架布局,提供更贴近真实内容的加载占位。
*/
type SkeletonVariant = "stats" | "card" | "chart" | "table" | "list"
export function DashboardSectionSkeleton({
variant = "card",
}: {
variant?: SkeletonVariant
}): ReactNode {
switch (variant) {
case "stats":
return (
{Array.from({ length: 4 }).map((_, i) => (
))}
)
case "chart":
return (
)
case "table":
return (
{Array.from({ length: 5 }).map((_, i) => (
))}
)
case "list":
return (
{Array.from({ length: 4 }).map((_, i) => (
))}
)
case "card":
default:
return (
)
}
}
/**
* 仪表盘分区包装器
*
* 组合 Error Boundary + Suspense + 骨架屏,包裹每个独立数据区块。
* 单个区块出错或加载中时,仅影响该区块,不波及整页。
*
* 使用共享 SectionErrorBoundary 替代模块特定的 DashboardSectionErrorBoundary 类。
*
* V4(P3-1)新增 `ariaLabel` prop:传入时渲染 ``,
* 使键盘用户可按逻辑顺序遍历各 Widget,提升 a11y。
*
* @example
*
*
*
*/
export function DashboardSection({
children,
variant = "card",
ariaLabel,
}: {
children: ReactNode
variant?: SkeletonVariant
/** 传入时渲染为可聚焦的 region,提升键盘导航 a11y */
ariaLabel?: string
}): ReactNode {
const t = useTranslations("dashboard.error")
const fallback = (): ReactNode => (
window.location.reload() }}
className="h-auto border-none shadow-none"
/>
)
const content = (
}>
{children}
)
if (ariaLabel) {
return (
)
}
return content
}