Files
hristudio/src/components/admin/system-stats.tsx
Sean O'Connor 544207e9a2 Enhance development standards and UI components
- Updated .rules to enforce stricter UI/UX standards, including exclusive use of Lucide icons and consistent patterns for entity view pages.
- Added new UI components for entity views, including headers, sections, and quick actions to improve layout and reusability.
- Refactored existing pages (experiments, participants, studies, trials) to utilize the new entity view components, enhancing consistency across the dashboard.
- Improved accessibility and user experience by implementing loading states and error boundaries in async operations.
- Updated package dependencies to ensure compatibility and performance improvements.

Features:
- Comprehensive guidelines for component reusability and visual consistency.
- Enhanced user interface with new entity view components for better organization and navigation.

Breaking Changes: None - existing functionality remains intact.
2025-08-05 02:36:44 -04:00

191 lines
5.9 KiB
TypeScript

"use client";
import { Badge } from "~/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
export function SystemStats() {
// TODO: Implement admin.getSystemStats API endpoint
// const { data: stats, isLoading } = api.admin.getSystemStats.useQuery({});
const isLoading = false;
if (isLoading) {
return (
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
{Array.from({ length: 4 }).map((_, i) => (
<Card key={i} className="animate-pulse">
<CardHeader className="pb-2">
<div className="h-4 w-20 rounded bg-slate-200"></div>
</CardHeader>
<CardContent>
<div className="mb-2 h-8 w-12 rounded bg-slate-200"></div>
<div className="h-3 w-24 rounded bg-slate-200"></div>
</CardContent>
</Card>
))}
</div>
);
}
// Mock data for now since we don't have the actual admin router implemented
const mockStats = {
totalUsers: 42,
totalStudies: 15,
totalExperiments: 38,
totalTrials: 127,
activeTrials: 3,
systemHealth: "healthy",
uptime: "7 days, 14 hours",
storageUsed: "2.3 GB",
};
const displayStats = mockStats;
return (
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
{/* Total Users */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-muted-foreground text-sm font-medium">
Total Users
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{displayStats.totalUsers}</div>
<div className="mt-1 flex items-center gap-2">
<Badge variant="secondary" className="text-xs">
All roles
</Badge>
</div>
</CardContent>
</Card>
{/* Total Studies */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-muted-foreground text-sm font-medium">
Studies
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{displayStats.totalStudies}</div>
<div className="mt-1 flex items-center gap-2">
<Badge variant="secondary" className="text-xs">
Active
</Badge>
</div>
</CardContent>
</Card>
{/* Total Experiments */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-muted-foreground text-sm font-medium">
Experiments
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">
{displayStats.totalExperiments}
</div>
<div className="mt-1 flex items-center gap-2">
<Badge variant="secondary" className="text-xs">
Published
</Badge>
</div>
</CardContent>
</Card>
{/* Total Trials */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-muted-foreground text-sm font-medium">
Trials
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{displayStats.totalTrials}</div>
<div className="mt-1 flex items-center gap-2">
<Badge variant="outline" className="text-xs">
{displayStats.activeTrials} running
</Badge>
</div>
</CardContent>
</Card>
{/* System Health */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-muted-foreground text-sm font-medium">
System Health
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex items-center gap-2">
<div className="flex h-3 w-3 items-center justify-center">
<div className="h-2 w-2 rounded-full bg-green-500"></div>
</div>
<span className="text-sm font-medium text-green-600">
{displayStats.systemHealth === "healthy" ? "Healthy" : "Issues"}
</span>
</div>
<div className="text-muted-foreground mt-1 text-xs">
All services operational
</div>
</CardContent>
</Card>
{/* Uptime */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-muted-foreground text-sm font-medium">
Uptime
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-sm font-medium">{displayStats.uptime}</div>
<div className="text-muted-foreground mt-1 text-xs">
Since last restart
</div>
</CardContent>
</Card>
{/* Storage Usage */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-muted-foreground text-sm font-medium">
Storage Used
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-sm font-medium">{displayStats.storageUsed}</div>
<div className="text-muted-foreground mt-1 text-xs">
Media & database
</div>
</CardContent>
</Card>
{/* Recent Activity */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-muted-foreground text-sm font-medium">
Recent Activity
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-1">
<div className="text-muted-foreground text-xs">
2 trials started today
</div>
<div className="text-muted-foreground text-xs">
1 new user registered
</div>
<div className="text-muted-foreground text-xs">
3 experiments published
</div>
</div>
</CardContent>
</Card>
</div>
);
}