75 lines
3.1 KiB
TypeScript
75 lines
3.1 KiB
TypeScript
import React from 'react';
|
|
|
|
export function Skeleton({ className = '', ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
return <div className={`skeleton ${className}`} {...props} />;
|
|
}
|
|
|
|
export function TableSkeleton({ rows = 8 }: { rows?: number }) {
|
|
return (
|
|
<div className="w-full" role="status" aria-label="Loading">
|
|
<table className="w-full table-fixed border-separate text-left">
|
|
<thead className="text-xs font-semibold text-gray-600 uppercase tracking-wider">
|
|
<tr>
|
|
<th className="pb-3 border-b border-gray-200 w-[40%]">Subject</th>
|
|
<th className="pb-3 border-b border-gray-200 w-[15%]">Date</th>
|
|
<th className="pb-3 border-b border-gray-200 w-[22%]">Key</th>
|
|
<th className="pb-3 border-b border-gray-200 w-[12%]">Proc. By</th>
|
|
<th className="pb-3 border-b border-gray-200 w-[11%]">Queued</th>
|
|
<th className="pb-3 border-b border-gray-200 w-[10%]">Status</th>
|
|
<th className="pb-3 border-b border-gray-200 text-right w-[10%]">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="text-sm">
|
|
{Array.from({ length: rows }).map((_, i) => (
|
|
<tr key={i}>
|
|
<td className="py-2"><Skeleton className="h-4 w-3/4" /></td>
|
|
<td className="py-2"><Skeleton className="h-4 w-20" /></td>
|
|
<td className="py-2"><Skeleton className="h-4 w-32" /></td>
|
|
<td className="py-2"><Skeleton className="h-4 w-16" /></td>
|
|
<td className="py-2"><Skeleton className="h-4 w-16" /></td>
|
|
<td className="py-2"><Skeleton className="h-4 w-16" /></td>
|
|
<td className="py-2 text-right"><Skeleton className="h-4 w-12 ml-auto" /></td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
<span className="sr-only">Loading emails...</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function CardSkeleton({ count = 5 }: { count?: number }) {
|
|
return (
|
|
<div className="max-w-md mx-auto grid gap-4 fade-in-stagger" role="status" aria-label="Loading">
|
|
{Array.from({ length: count }).map((_, i) => (
|
|
<div key={i} className="p-6 bg-white rounded-lg shadow-md">
|
|
<Skeleton className="h-6 w-3/4" />
|
|
</div>
|
|
))}
|
|
<span className="sr-only">Loading items...</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function DetailSkeleton() {
|
|
return (
|
|
<div className="max-w-4xl mx-auto bg-white rounded-lg shadow-md p-8 fade-in" role="status" aria-label="Loading">
|
|
<Skeleton className="h-10 w-3/4 mb-6" />
|
|
<div className="grid grid-cols-2 gap-4 mb-6 bg-gray-50 p-6 rounded-lg">
|
|
<div className="space-y-3">
|
|
<Skeleton className="h-4 w-full" />
|
|
<Skeleton className="h-4 w-full" />
|
|
<Skeleton className="h-4 w-2/3" />
|
|
</div>
|
|
<div className="space-y-3">
|
|
<Skeleton className="h-4 w-full" />
|
|
<Skeleton className="h-4 w-full" />
|
|
<Skeleton className="h-4 w-3/4" />
|
|
</div>
|
|
</div>
|
|
<Skeleton className="h-96 w-full" />
|
|
<span className="sr-only">Loading email details...</span>
|
|
</div>
|
|
);
|
|
}
|