feat: add status summary cards to All Applications page
- Show running, deploying, pending, stopped, failed counts as color-coded cards - Cards displayed at top of All Applications page for quick status overview - Skeleton loading state includes card placeholders
This commit is contained in:
@@ -47,12 +47,34 @@ export default function AdminAppsPage() {
|
||||
onError: () => toast.error('Failed to delete application'),
|
||||
});
|
||||
|
||||
// Compute status counts from apps
|
||||
const statusCounts = apps.reduce(
|
||||
(acc, app) => {
|
||||
const status = app.deployments?.[0]?.status || 'pending';
|
||||
if (status === 'running') acc.running++;
|
||||
else if (status === 'stopped') acc.stopped++;
|
||||
else if (status === 'failed' || status === 'build_failed') acc.failed++;
|
||||
else if (status === 'building' || status === 'deploying') acc.deploying++;
|
||||
else acc.pending++;
|
||||
return acc;
|
||||
},
|
||||
{ running: 0, stopped: 0, failed: 0, deploying: 0, pending: 0 },
|
||||
);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="page-header">
|
||||
<div className="skeleton h-8 w-56" />
|
||||
</div>
|
||||
<div className="grid grid-cols-2 md:grid-cols-5 gap-3">
|
||||
{[1, 2, 3, 4, 5].map((i) => (
|
||||
<div key={i} className="card py-4">
|
||||
<div className="skeleton h-8 w-12 mx-auto mb-2" />
|
||||
<div className="skeleton h-3 w-16 mx-auto" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="skeleton h-10 w-full rounded-xl" />
|
||||
<div className="space-y-3">
|
||||
{[1, 2, 3, 4].map((i) => (
|
||||
@@ -82,6 +104,30 @@ export default function AdminAppsPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Status Summary Cards */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-5 gap-3">
|
||||
<div className="card py-4 text-center border-l-4 border-l-green-500">
|
||||
<p className="text-2xl font-bold text-green-600">{statusCounts.running}</p>
|
||||
<p className="text-xs text-gray-500 font-medium mt-1">Running</p>
|
||||
</div>
|
||||
<div className="card py-4 text-center border-l-4 border-l-blue-500">
|
||||
<p className="text-2xl font-bold text-blue-600">{statusCounts.deploying}</p>
|
||||
<p className="text-xs text-gray-500 font-medium mt-1">Deploying</p>
|
||||
</div>
|
||||
<div className="card py-4 text-center border-l-4 border-l-yellow-500">
|
||||
<p className="text-2xl font-bold text-yellow-600">{statusCounts.pending}</p>
|
||||
<p className="text-xs text-gray-500 font-medium mt-1">Pending</p>
|
||||
</div>
|
||||
<div className="card py-4 text-center border-l-4 border-l-gray-400">
|
||||
<p className="text-2xl font-bold text-gray-500">{statusCounts.stopped}</p>
|
||||
<p className="text-xs text-gray-500 font-medium mt-1">Stopped</p>
|
||||
</div>
|
||||
<div className="card py-4 text-center border-l-4 border-l-red-500">
|
||||
<p className="text-2xl font-bold text-red-600">{statusCounts.failed}</p>
|
||||
<p className="text-xs text-gray-500 font-medium mt-1">Failed</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Search */}
|
||||
<div className="relative">
|
||||
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 text-base">🔍</span>
|
||||
|
||||
Reference in New Issue
Block a user