Files
ember-market-frontend/components/dashboard/page-loading.tsx
2025-03-24 13:43:42 +00:00

114 lines
4.3 KiB
TypeScript

"use client"
import { Skeleton } from "@/components/ui/skeleton";
import { Card } from "@/components/ui/card";
import { Loader2 } from "lucide-react";
interface PageLoadingProps {
title?: string;
subtitle?: string;
itemsCount?: number;
layout?: 'list' | 'grid' | 'table';
}
export default function PageLoading({
title = "Loading data...",
subtitle,
itemsCount = 5,
layout = 'list'
}: PageLoadingProps) {
return (
<div className="space-y-6 animate-in fade-in duration-300">
{/* Header skeleton */}
<div className="flex items-center justify-between">
<div>
<Skeleton className="h-8 w-72 mb-2" />
{subtitle && <Skeleton className="h-4 w-96" />}
</div>
<Skeleton className="h-10 w-28" />
</div>
{/* Main content skeleton */}
<Card className="relative overflow-hidden">
<div className="absolute inset-0 flex items-center justify-center z-10 pointer-events-none">
<div className="flex flex-col items-center justify-center bg-background/80 backdrop-blur-[2px] p-6 rounded-lg shadow-sm">
<Loader2 className="h-10 w-10 animate-spin text-primary mb-3" />
<p className="text-lg font-medium">{title}</p>
{subtitle && <p className="text-sm text-muted-foreground">{subtitle}</p>}
</div>
</div>
{layout === 'list' && (
<div className="p-6 space-y-4 opacity-30">
{[...Array(itemsCount)].map((_, i) => (
<div key={i} className="flex items-center gap-4 p-3 border-b last:border-0">
<Skeleton className="h-12 w-12 rounded-md" />
<div className="space-y-2 flex-1">
<Skeleton className="h-4 w-full max-w-[280px]" />
<Skeleton className="h-4 w-20" />
</div>
<div className="ml-auto text-right flex gap-2">
<Skeleton className="h-9 w-9 rounded-md" />
<Skeleton className="h-9 w-9 rounded-md" />
</div>
</div>
))}
</div>
)}
{layout === 'grid' && (
<div className="p-6 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 opacity-30">
{[...Array(itemsCount)].map((_, i) => (
<Card key={i} className="p-4">
<Skeleton className="h-32 w-full rounded-md mb-3" />
<Skeleton className="h-5 w-3/4 mb-2" />
<Skeleton className="h-4 w-1/2 mb-3" />
<div className="flex justify-between items-center mt-2">
<Skeleton className="h-6 w-16" />
<Skeleton className="h-8 w-8 rounded-full" />
</div>
</Card>
))}
</div>
)}
{layout === 'table' && (
<div className="w-full opacity-30">
<div className="border-b px-6 py-4">
<div className="flex gap-4">
<Skeleton className="h-4 w-32" />
<Skeleton className="h-4 w-32" />
<Skeleton className="h-4 w-32" />
<Skeleton className="h-4 w-32" />
</div>
</div>
<div className="divide-y">
{[...Array(itemsCount)].map((_, i) => (
<div key={i} className="px-6 py-4">
<div className="flex justify-between items-center">
<div className="space-y-2 flex-1">
<Skeleton className="h-4 w-40" />
<Skeleton className="h-4 w-24" />
</div>
<div className="space-y-2 flex-1">
<Skeleton className="h-4 w-32" />
<Skeleton className="h-4 w-20" />
</div>
<div className="space-y-2 flex-1">
<Skeleton className="h-4 w-28" />
</div>
<div className="flex gap-2">
<Skeleton className="h-8 w-8 rounded-md" />
<Skeleton className="h-8 w-8 rounded-md" />
</div>
</div>
</div>
))}
</div>
</div>
)}
</Card>
</div>
);
}