All files / components/ui page-loader.tsx

100% Statements 53/53
100% Branches 7/7
100% Functions 4/4
100% Lines 53/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 731x                     1x 10x 10x 10x 10x 10x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x   4x   6x 6x 6x 6x 6x 6x 6x   6x   1x 2x 2x 2x 2x 2x 2x   2x   1x 3x 3x 3x 3x 3x 3x 3x 3x   3x   1x 5x 5x 5x 5x 20x 5x 5x   5x  
'use client';
 
import { Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';
 
interface PageLoaderProps {
  className?: string;
  text?: string;
  fullScreen?: boolean;
}
 
export function PageLoader({
  className,
  text = 'Loading...',
  fullScreen = false,
}: PageLoaderProps) {
  if (fullScreen) {
    return (
      <div className="fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm">
        <div className="flex flex-col items-center gap-4 duration-300 animate-in fade-in">
          <div className="relative">
            <div className="h-12 w-12 rounded-full border-4 border-muted" />
            <div className="absolute inset-0 h-12 w-12 animate-spin rounded-full border-4 border-primary border-t-transparent" />
          </div>
          <p className="animate-pulse text-sm text-muted-foreground">{text}</p>
        </div>
      </div>
    );
  }
 
  return (
    <div className={cn('flex min-h-[400px] items-center justify-center', className)}>
      <div className="flex flex-col items-center gap-4 duration-300 animate-in fade-in">
        <Loader2 className="h-8 w-8 animate-spin text-primary" />
        <p className="text-sm text-muted-foreground">{text}</p>
      </div>
    </div>
  );
}
 
export function CardSkeleton() {
  return (
    <div className="animate-pulse rounded-lg border bg-card p-6">
      <div className="skeleton mb-4 h-4 w-1/3 rounded" />
      <div className="skeleton mb-2 h-3 w-full rounded" />
      <div className="skeleton h-3 w-2/3 rounded" />
    </div>
  );
}
 
export function ProfileSkeleton() {
  return (
    <div className="flex animate-pulse items-center gap-4">
      <div className="skeleton h-16 w-16 rounded-full" />
      <div className="space-y-2">
        <div className="skeleton h-4 w-32 rounded" />
        <div className="skeleton h-3 w-24 rounded" />
      </div>
    </div>
  );
}
 
export function TableSkeleton({ rows = 5 }: { rows?: number }) {
  return (
    <div className="animate-pulse space-y-3">
      <div className="skeleton h-10 rounded" />
      {Array.from({ length: rows }).map((_, i) => (
        <div key={i} className="skeleton h-12 rounded" />
      ))}
    </div>
  );
}