/** * Reusable skeleton loading primitives and composites for Pulse. * All skeletons follow the design-system pattern: * animate-pulse + bg-neutral-100 dark:bg-neutral-800 + rounded */ const SK = 'animate-pulse bg-neutral-100 dark:bg-neutral-800' export { useMinimumLoading } from './useMinimumLoading' // ─── Primitives ────────────────────────────────────────────── export function SkeletonLine({ className = '' }: { className?: string }) { return
} export function SkeletonCircle({ className = '' }: { className?: string }) { return
} export function SkeletonCard({ className = '' }: { className?: string }) { return
} // ─── List skeleton (icon + two text lines per row) ─────────── export function ListRowSkeleton() { return (
) } export function ListSkeleton({ rows = 7 }: { rows?: number }) { return (
{Array.from({ length: rows }).map((_, i) => ( ))}
) } // ─── Table skeleton (header row + data rows) ───────────────── export function TableSkeleton({ rows = 7, cols = 5 }: { rows?: number; cols?: number }) { return (
{Array.from({ length: cols }).map((_, i) => ( ))}
{Array.from({ length: rows }).map((_, i) => (
{Array.from({ length: cols }).map((_, j) => ( ))}
))}
) } // ─── Widget panel skeleton (used inside dashboard grid) ────── export function WidgetSkeleton() { return (
) } // ─── Stat card skeleton ────────────────────────────────────── export function StatCardSkeleton() { return (
) } // ─── Chart area skeleton ───────────────────────────────────── export function ChartSkeleton() { return (
{Array.from({ length: 4 }).map((_, i) => (
))}
) } // ─── Full dashboard skeleton ───────────────────────────────── export function DashboardSkeleton() { return (
{/* Header */}
{/* Chart */}
{/* Widget grid (2 cols) */}
{/* Campaigns table */}
) } // ─── Journeys page skeleton ───────────────────────────────── export function JourneysSkeleton() { return (
{/* Header */}
{/* Controls */}
{/* Sankey area */} {/* Top paths table */}
) } // ─── Uptime page skeleton ──────────────────────────────────── export function UptimeSkeleton() { return (
{/* Overall status */} {/* Monitor cards */}
{Array.from({ length: 3 }).map((_, i) => (
))}
) } // ─── Checks / Response time skeleton ───────────────────────── export function ChecksSkeleton() { return (
{Array.from({ length: 5 }).map((_, i) => (
))}
) } // ─── Funnels list skeleton ─────────────────────────────────── export function FunnelsListSkeleton() { return (
{Array.from({ length: 3 }).map((_, i) => (
{Array.from({ length: 3 }).map((_, j) => (
{j < 2 && }
))}
))}
) } // ─── Funnel detail skeleton ────────────────────────────────── export function FunnelDetailSkeleton() { return (
{Array.from({ length: 3 }).map((_, i) => ( ))}
) } // ─── Notifications list skeleton ───────────────────────────── export function NotificationsListSkeleton() { return (
{Array.from({ length: 6 }).map((_, i) => (
))}
) } // ─── Settings form skeleton ────────────────────────────────── export function SettingsFormSkeleton() { return (
{Array.from({ length: 4 }).map((_, i) => (
))}
) } // ─── Goals list skeleton ───────────────────────────────────── export function GoalsListSkeleton() { return (
{Array.from({ length: 3 }).map((_, i) => (
))}
) } // ─── Pricing cards skeleton ────────────────────────────────── export function PricingCardsSkeleton() { return (
{Array.from({ length: 3 }).map((_, i) => ( ))}
) } // ─── Organization settings skeleton (members, billing, etc) ─ export function MembersListSkeleton() { return (
{Array.from({ length: 4 }).map((_, i) => (
))}
) } export function InvoicesListSkeleton() { return (
{Array.from({ length: 4 }).map((_, i) => (
))}
) } export function AuditLogSkeleton() { return (
{Array.from({ length: 5 }).map((_, i) => (
))}
) }