"use client" import * as React from "react" import { cn } from "../../lib/utils" import { Skeleton } from "../ui/skeleton" /** * ListPageLoadingFallback — a skeleton that mirrors the real `ListPageTemplate` * chrome so the first paint after a route change already feels like the final hub. * * Use it as the `fallback` for any `` that wraps a hub route that * renders ``. * * It shows: * - A header bar placeholder * - The view segmented toolbar (fake tabs + count pills) * - A flat KeyMetrics band skeleton * - A DataTable header row + several data rows * * This prevents the "empty white → full chrome" flash the user complained about. */ export function ListPageLoadingFallback({ showMetrics = true, tabCount = 4, rowCount = 6, className, }: { /** Whether to show the metrics band skeleton (match the real page) */ showMetrics?: boolean /** How many fake view tabs to render in the toolbar skeleton */ tabCount?: number /** How many data rows to show under the table header */ rowCount?: number className?: string }) { return (
{/* Header area (title + actions) */}
{/* Optional metrics strip (flat band style) */} {showMetrics && (
{Array.from({ length: 4 }).map((_, i) => (
))}
)} {/* Views toolbar skeleton (matches the real segmented control) */}
{Array.from({ length: tabCount }).map((_, i) => (
{/* Fake count pill */}
))} {/* Add view ghost — a square, because the real trigger is a lone glyph and a label-width placeholder would shuffle the rail on hydrate. */}
{/* Table header + rows skeleton */}
{/* Header row */}
{/* Data rows */} {Array.from({ length: rowCount }).map((_, i) => (
))}
) }