239 lines
9.1 KiB
TypeScript
239 lines
9.1 KiB
TypeScript
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import {
|
|
Users,
|
|
FileText,
|
|
MessageSquare,
|
|
TrendingUp,
|
|
AlertTriangle,
|
|
CheckCircle,
|
|
Clock,
|
|
BarChart3
|
|
} from 'lucide-react';
|
|
|
|
interface AdminDashboardProps {
|
|
onCreateUser: () => void;
|
|
onViewScripts: () => void;
|
|
onViewAnalytics: () => void;
|
|
}
|
|
|
|
export function AdminDashboard({ onCreateUser, onViewScripts, onViewAnalytics }: AdminDashboardProps) {
|
|
// Mock data - in a real app, this would come from API calls
|
|
const stats = {
|
|
totalUsers: 1247,
|
|
totalScripts: 89,
|
|
pendingApprovals: 12,
|
|
totalComments: 456,
|
|
activeUsers: 234,
|
|
scriptsThisWeek: 8,
|
|
commentsThisWeek: 23,
|
|
systemHealth: 'healthy'
|
|
};
|
|
|
|
const recentActivity = [
|
|
{ id: 1, type: 'script', action: 'submitted', title: 'Docker Setup Script', user: 'john_doe', time: '2 hours ago' },
|
|
{ id: 2, type: 'comment', action: 'reported', title: 'Comment on Backup Script', user: 'jane_smith', time: '4 hours ago' },
|
|
{ id: 3, type: 'user', action: 'registered', title: 'New user account', user: 'alex_wilson', time: '6 hours ago' },
|
|
{ id: 4, type: 'script', action: 'approved', title: 'Network Monitor', user: 'admin', time: '1 day ago' },
|
|
];
|
|
|
|
const getActivityIcon = (type: string) => {
|
|
switch (type) {
|
|
case 'script': return <FileText className="h-4 w-4" />;
|
|
case 'comment': return <MessageSquare className="h-4 w-4" />;
|
|
case 'user': return <Users className="h-4 w-4" />;
|
|
default: return <BarChart3 className="h-4 w-4" />;
|
|
}
|
|
};
|
|
|
|
const getActivityColor = (type: string) => {
|
|
switch (type) {
|
|
case 'script': return 'text-blue-600';
|
|
case 'comment': return 'text-green-600';
|
|
case 'user': return 'text-purple-600';
|
|
default: return 'text-gray-600';
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Quick Stats */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">Total Users</CardTitle>
|
|
<Users className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold">{stats.totalUsers.toLocaleString()}</div>
|
|
<p className="text-xs text-muted-foreground">
|
|
+{stats.activeUsers} active this month
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">Total Scripts</CardTitle>
|
|
<FileText className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold">{stats.totalScripts}</div>
|
|
<p className="text-xs text-muted-foreground">
|
|
+{stats.scriptsThisWeek} this week
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">Pending Approvals</CardTitle>
|
|
<Clock className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold text-amber-600">{stats.pendingApprovals}</div>
|
|
<p className="text-xs text-muted-foreground">
|
|
Require attention
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">System Health</CardTitle>
|
|
<CheckCircle className="h-4 w-4 text-green-600" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold text-green-600 capitalize">{stats.systemHealth}</div>
|
|
<p className="text-xs text-muted-foreground">
|
|
All systems operational
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
{/* Quick Actions */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Quick Actions</CardTitle>
|
|
<CardDescription>
|
|
Common administrative tasks and shortcuts.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<Button
|
|
onClick={onCreateUser}
|
|
className="h-20 flex flex-col items-center justify-center gap-2"
|
|
>
|
|
<Users className="h-6 w-6" />
|
|
<span>Create Admin User</span>
|
|
</Button>
|
|
|
|
<Button
|
|
onClick={onViewScripts}
|
|
variant="outline"
|
|
className="h-20 flex flex-col items-center justify-center gap-2"
|
|
>
|
|
<FileText className="h-6 w-6" />
|
|
<span>Review Scripts</span>
|
|
</Button>
|
|
|
|
<Button
|
|
onClick={onViewAnalytics}
|
|
variant="outline"
|
|
className="h-20 flex flex-col items-center justify-center gap-2"
|
|
>
|
|
<BarChart3 className="h-6 w-6" />
|
|
<span>View Analytics</span>
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Recent Activity */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Recent Activity</CardTitle>
|
|
<CardDescription>
|
|
Latest platform activities requiring attention.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-3">
|
|
{recentActivity.map((activity) => (
|
|
<div key={activity.id} className="flex items-center gap-3 p-3 rounded-lg hover:bg-muted/50 transition-colors">
|
|
<div className={`p-2 rounded-full bg-muted ${getActivityColor(activity.type)}`}>
|
|
{getActivityIcon(activity.type)}
|
|
</div>
|
|
|
|
<div className="flex-1 min-w-0">
|
|
<div className="flex items-center gap-2">
|
|
<span className="font-medium text-sm">
|
|
{activity.title}
|
|
</span>
|
|
<Badge variant="outline" className="text-xs">
|
|
{activity.action}
|
|
</Badge>
|
|
</div>
|
|
<div className="text-xs text-muted-foreground">
|
|
by @{activity.user} • {activity.time}
|
|
</div>
|
|
</div>
|
|
|
|
<Button variant="ghost" size="sm">
|
|
View
|
|
</Button>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* System Status */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>System Status</CardTitle>
|
|
<CardDescription>
|
|
Current platform status and alerts.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-4">
|
|
<div className="flex items-center justify-between p-3 bg-green-50 dark:bg-green-950/20 border border-green-200 dark:border-green-800 rounded-lg">
|
|
<div className="flex items-center gap-2">
|
|
<CheckCircle className="h-4 w-4 text-green-600" />
|
|
<span className="font-medium text-green-800 dark:text-green-200">Database</span>
|
|
</div>
|
|
<Badge variant="secondary" className="bg-green-100 text-green-800">
|
|
Operational
|
|
</Badge>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between p-3 bg-green-50 dark:bg-green-950/20 border border-green-200 dark:border-green-800 rounded-lg">
|
|
<div className="flex items-center gap-2">
|
|
<CheckCircle className="h-4 w-4 text-green-600" />
|
|
<span className="font-medium text-green-800 dark:text-green-200">File Storage</span>
|
|
</div>
|
|
<Badge variant="secondary" className="bg-green-100 text-green-800">
|
|
Operational
|
|
</Badge>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between p-3 bg-green-50 dark:bg-green-950/20 border border-green-200 dark:border-green-800 rounded-lg">
|
|
<div className="flex items-center gap-2">
|
|
<CheckCircle className="h-4 w-4 text-green-600" />
|
|
<span className="font-medium text-green-800 dark:text-green-200">Email Service</span>
|
|
</div>
|
|
<Badge variant="secondary" className="bg-green-100 text-green-800">
|
|
Operational
|
|
</Badge>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|