feat: Implement skeleton loading

This commit is contained in:
gpt-engineer-app[bot]
2025-10-10 15:18:02 +00:00
parent c4b3886ffc
commit a16154c3de
8 changed files with 171 additions and 35 deletions

View File

@@ -23,6 +23,7 @@ import { ReassignDialog } from './ReassignDialog';
import { smartMergeArray } from '@/lib/smartStateUpdate';
import { useDebounce } from '@/hooks/useDebounce';
import { QueueItem } from './QueueItem';
import { QueueSkeleton } from './QueueSkeleton';
interface ModerationItem {
id: string;
@@ -1678,11 +1679,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
const QueueContent = () => {
if (isInitialLoad && loading) {
return (
<div className="flex items-center justify-center p-8">
<div className="animate-spin rounded-full h-6 w-6 border-b-2 border-primary"></div>
</div>
);
return <QueueSkeleton count={5} />;
}
if (items.length === 0) {

View File

@@ -0,0 +1,42 @@
import { Card, CardHeader, CardContent } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
export function QueueItemSkeleton() {
return (
<Card className="border-l-4 border-l-muted">
<CardHeader className="pb-4">
<div className="flex items-start justify-between gap-4">
{/* Left side: Entity type badge + title */}
<div className="flex-1 space-y-3">
<Skeleton className="h-5 w-24" /> {/* Badge */}
<Skeleton className="h-6 w-3/4" /> {/* Title */}
<div className="flex items-center gap-2">
<Skeleton className="h-4 w-4 rounded-full" /> {/* Avatar */}
<Skeleton className="h-4 w-32" /> {/* Username */}
<Skeleton className="h-4 w-24" /> {/* Date */}
</div>
</div>
{/* Right side: Status badge */}
<Skeleton className="h-6 w-20" />
</div>
</CardHeader>
<CardContent className="space-y-4">
{/* Content area */}
<div className="space-y-2">
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-5/6" />
<Skeleton className="h-4 w-4/6" />
</div>
{/* Action buttons */}
<div className="flex gap-2 pt-4">
<Skeleton className="h-9 w-24" />
<Skeleton className="h-9 w-24" />
<Skeleton className="h-9 w-24" />
</div>
</CardContent>
</Card>
);
}

View File

@@ -0,0 +1,15 @@
import { QueueItemSkeleton } from './QueueItemSkeleton';
interface QueueSkeletonProps {
count?: number;
}
export function QueueSkeleton({ count = 5 }: QueueSkeletonProps) {
return (
<div className="flex flex-col gap-6">
{Array.from({ length: count }).map((_, i) => (
<QueueItemSkeleton key={i} />
))}
</div>
);
}