- error.tsx -> ErrorPage (keep telemetry on mount; retry wired to Next reset). - (dashboard)/loading.tsx -> LoadingSpinner inside the existing skeleton. - not-found.tsx already used NotFoundPage (confirmed, unchanged). - dashboard overview page.tsx header -> PageHeader (Refresh as actions; the subtitle/last-updated line preserved directly below). Rich detail headers (e.g. users/[id] back-button + plan/status badges) left bespoke on purpose: PageHeader has no subtitle/badge slot, so forcing it would regress them (additive-only rule). dashboard-components reads --color-* which admin maps via @theme inline, so it themes in light + dark. Verify: typecheck+lint+build green (123 routes); vitest 20 files / 168 tests (+3 happy-dom chrome render tests); format:check no new failures; e2e 11 passed / 80 failed (unchanged vs UX-1 baseline — environmental). Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
40 lines
1.4 KiB
TypeScript
40 lines
1.4 KiB
TypeScript
import { LoadingSpinner } from '@bytelyst/dashboard-components';
|
|
|
|
export default function DashboardLoading() {
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Header skeleton */}
|
|
<div className="space-y-2">
|
|
<div className="h-8 w-48 animate-pulse rounded bg-muted" />
|
|
<div className="h-4 w-72 animate-pulse rounded bg-muted" />
|
|
</div>
|
|
|
|
{/* KPI cards skeleton */}
|
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
|
{Array.from({ length: 4 }).map((_, i) => (
|
|
<div key={i} className="rounded-xl border bg-card p-6">
|
|
<div className="flex items-center justify-between">
|
|
<div className="h-4 w-24 animate-pulse rounded bg-muted" />
|
|
<div className="h-8 w-8 animate-pulse rounded bg-muted" />
|
|
</div>
|
|
<div className="mt-3 h-7 w-20 animate-pulse rounded bg-muted" />
|
|
<div className="mt-1 h-3 w-32 animate-pulse rounded bg-muted" />
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Chart skeleton */}
|
|
<div className="grid gap-4 lg:grid-cols-2">
|
|
{Array.from({ length: 2 }).map((_, i) => (
|
|
<div key={i} className="rounded-xl border bg-card p-6">
|
|
<div className="mb-4 h-5 w-36 animate-pulse rounded bg-muted" />
|
|
<div className="flex items-center justify-center h-64">
|
|
<LoadingSpinner size="md" />
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|