Files
scriptshare-cursor-clone/src/components/admin/AdminDashboard.tsx

239 lines
9.1 KiB
TypeScript
Raw Normal View History

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>
);
}