import { useState, useEffect } from 'react' import type { NextPage } from 'next' import Head from 'next/head' import AdminLayout from '../../components/AdminLayout' import { ChartBarIcon, ShieldExclamationIcon, DocumentTextIcon, ExclamationTriangleIcon, ClockIcon, EyeIcon, ServerStackIcon, CircleStackIcon, UserGroupIcon, GlobeAltIcon, ArrowTrendingUpIcon, ArrowTrendingDownIcon, CheckCircleIcon } from '@heroicons/react/24/outline' import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, BarElement, Title, Tooltip, Legend, ArcElement, } from 'chart.js' import { Line, Bar, Doughnut } from 'react-chartjs-2' ChartJS.register( CategoryScale, LinearScale, PointElement, LineElement, BarElement, Title, Tooltip, Legend, ArcElement ) interface DashboardStats { // Basic stats total_sources: number pending_sources: number pending_reports: number high_risk_sources: number sources_added_week: number reports_today: number // Advanced stats verified_sources_today: number api_calls_today: number unique_visitors_today: number system_uptime: string database_size: string active_moderators: number // Performance metrics avg_response_time: number api_success_rate: number memory_usage: number cpu_usage: number // Trend data sources_trend: Array<{date: string, count: number}> reports_trend: Array<{date: string, count: number}> risk_distribution: Array<{level: string, count: number}> category_distribution: Array<{category: string, count: number}> // Recent activities recent_sources: Array<{ id: number url: string status: string created_at: string }> recent_reports: Array<{ id: number source_url: string status: string created_at: string }> } const StatCard = ({ title, value, change, icon: Icon, trend, color = 'blue' }: { title: string value: string | number change?: number icon: any trend?: 'up' | 'down' | 'neutral' color?: 'blue' | 'green' | 'red' | 'yellow' | 'purple' }) => { const colorClasses = { blue: 'bg-blue-500', green: 'bg-green-500', red: 'bg-red-500', yellow: 'bg-yellow-500', purple: 'bg-purple-500' } return (
{title}
{typeof value === 'number' ? value.toLocaleString() : value}
{change !== undefined && (
0 ? 'text-green-600' : change < 0 ? 'text-red-600' : 'text-gray-500' }`}> {change > 0 ? ( ) : change < 0 ? ( ) : null} {Math.abs(change)}%
)}
) } const AdminDashboard: NextPage = () => { const [stats, setStats] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { fetchStats() const interval = setInterval(fetchStats, 30000) // Refresh every 30 seconds return () => clearInterval(interval) }, []) const fetchStats = async () => { try { const response = await fetch('/api/admin/dashboard') if (response.ok) { const data = await response.json() setStats(data) } } catch (error) { console.error('Failed to fetch stats:', error) } finally { setLoading(false) } } // Chart configurations const sourcesChartData = { labels: stats?.sources_trend?.map(item => new Date(item.date).toLocaleDateString('sk-SK')) || [], datasets: [ { label: 'Nové zdroje', data: stats?.sources_trend?.map(item => item.count) || [], borderColor: 'rgb(59, 130, 246)', backgroundColor: 'rgba(59, 130, 246, 0.1)', tension: 0.4, }, ], } const reportsChartData = { labels: stats?.reports_trend?.map(item => new Date(item.date).toLocaleDateString('sk-SK')) || [], datasets: [ { label: 'Nové hlásenia', data: stats?.reports_trend?.map(item => item.count) || [], backgroundColor: 'rgba(34, 197, 94, 0.8)', borderColor: 'rgb(34, 197, 94)', borderWidth: 1, }, ], } const riskDistributionData = { labels: stats?.risk_distribution?.map(item => `Úroveň ${item.level}`) || [], datasets: [ { data: stats?.risk_distribution?.map(item => item.count) || [], backgroundColor: [ '#ef4444', // red '#f97316', // orange '#eab308', // yellow '#22c55e', // green '#3b82f6', // blue ], borderWidth: 2, borderColor: '#ffffff', }, ], } if (loading) { return ( Dashboard - Hliadka.sk Admin
) } return ( Dashboard - Hliadka.sk Admin {/* Key Metrics */}
{/* System Performance Metrics */}
{/* Charts Section */}
{/* Sources Trend */}

Trend pridávania zdrojov

{/* Reports Trend */}

Trend hlásení

{/* Risk Distribution and Category Stats */}

Distribúcia rizika

Systémové informácie

Uptime systému
{stats?.system_uptime || 'N/A'}
Veľkosť databázy
{stats?.database_size || 'N/A'}
Priemerný response time
{stats?.avg_response_time || 0}ms
Využitie pamäte
{stats?.memory_usage || 0}%
Jedinečných návštevníkov dnes
{stats?.unique_visitors_today || 0}
Overených zdrojov dnes
{stats?.verified_sources_today || 0}
{/* Recent Activity */}

Najnovšie zdroje

    {stats?.recent_sources?.map((source, idx) => (
  • {idx !== (stats.recent_sources?.length || 0) - 1 && (
  • )) || (
  • Žiadne nedávne aktivity
  • )}

Najnovšie hlásenia

    {stats?.recent_reports?.map((report, idx) => (
  • {idx !== (stats.recent_reports?.length || 0) - 1 && (
  • )) || (
  • Žiadne nedávne hlásenia
  • )}
) } export default AdminDashboard