import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '@/hooks/useAuth'; import { useUserRole } from '@/hooks/useUserRole'; import { useRateLimitStats, useRecentMetrics } from '@/hooks/useRateLimitMetrics'; import { useAlertConfigs, useAlertHistory, useUnresolvedAlerts, useUpdateAlertConfig, useResolveAlert } from '@/hooks/useRateLimitAlerts'; import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Switch } from '@/components/ui/switch'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell, LineChart, Line, Legend } from 'recharts'; import { Activity, Shield, TrendingUp, Users, Clock, AlertTriangle, Bell, BellOff, CheckCircle } from 'lucide-react'; import { Skeleton } from '@/components/ui/skeleton'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { ConfirmationDialog } from '@/components/moderation/ConfirmationDialog'; import { format } from 'date-fns'; const COLORS = ['hsl(var(--primary))', 'hsl(var(--secondary))', 'hsl(var(--accent))', 'hsl(var(--muted))', 'hsl(var(--destructive))']; export default function RateLimitMetrics() { useDocumentTitle('Rate Limit Metrics'); const navigate = useNavigate(); const { user } = useAuth(); const { isModerator, loading: rolesLoading } = useUserRole(); const [timeWindow, setTimeWindow] = useState(60000); // 1 minute default const [resolvingAlertId, setResolvingAlertId] = useState(null); const { data: stats, isLoading: statsLoading, error: statsError } = useRateLimitStats(timeWindow); const { data: recentData, isLoading: recentLoading } = useRecentMetrics(50); const { data: alertConfigs, isLoading: alertConfigsLoading } = useAlertConfigs(); const { data: alertHistory, isLoading: alertHistoryLoading } = useAlertHistory(50); const { data: unresolvedAlerts } = useUnresolvedAlerts(); const updateConfig = useUpdateAlertConfig(); const resolveAlert = useResolveAlert(); // Redirect if not authorized if (!rolesLoading && !isModerator()) { navigate('/'); return null; } if (!user || rolesLoading) { return (
{[1, 2, 3, 4].map((i) => ( ))}
); } const recentMetrics = recentData?.metrics || []; // Prepare chart data const tierData = stats?.tierDistribution ? Object.entries(stats.tierDistribution).map(([name, value]) => ({ name, value, })) : []; const topBlockedIPsData = stats?.topBlockedIPs || []; const topBlockedUsersData = stats?.topBlockedUsers || []; // Calculate block rate percentage const blockRatePercentage = stats?.blockRate ? (stats.blockRate * 100).toFixed(1) : '0.0'; return (
{/* Header */}

Rate Limit Metrics

Monitor rate limiting activity and patterns

{statsError && ( Failed to load metrics: {statsError instanceof Error ? statsError.message : 'Unknown error'} )} {/* Overview Stats */} {statsLoading ? (
{[1, 2, 3, 4].map((i) => ( ))}
) : (
Total Requests
{stats?.totalRequests || 0}

{stats?.allowedRequests || 0} allowed, {stats?.blockedRequests || 0} blocked

Block Rate
{blockRatePercentage}%

Percentage of blocked requests

Unique IPs
{stats?.uniqueIPs || 0}

Distinct client addresses

Unique Users
{stats?.uniqueUsers || 0}

Authenticated users

)} Overview Blocked Requests Recent Activity Alerts {unresolvedAlerts && unresolvedAlerts.length > 0 && ( {unresolvedAlerts.length} )} Configuration
{/* Tier Distribution */} Tier Distribution Requests by rate limit tier {tierData.length > 0 ? ( `${name}: ${(percent * 100).toFixed(0)}%`} outerRadius={80} fill="hsl(var(--primary))" dataKey="value" > {tierData.map((entry, index) => ( ))} ) : (
No data available
)}
{/* Request Status */} Request Status Allowed vs blocked requests
{/* Top Blocked IPs */} Top Blocked IPs Most frequently blocked IP addresses {topBlockedIPsData.length > 0 ? ( ) : (
No blocked IPs in this time window
)}
{/* Top Blocked Users */} Top Blocked Users Most frequently blocked authenticated users {topBlockedUsersData.length > 0 ? (
{topBlockedUsersData.map((user, idx) => (
{user.userId} {user.count}
))}
) : (
No blocked users in this time window
)}
Recent Activity Last 50 rate limit checks {recentLoading ? (
{[1, 2, 3].map((i) => ( ))}
) : recentMetrics.length > 0 ? (
{recentMetrics.map((metric, idx) => (
{metric.functionName} {metric.allowed ? 'Allowed' : 'Blocked'} {metric.tier}
IP: {metric.clientIP} {metric.userId && `• User: ${metric.userId.slice(0, 8)}...`}
{metric.allowed ? `${metric.remaining} left` : `Retry: ${metric.retryAfter}s`}
{format(new Date(metric.timestamp), 'HH:mm:ss')}
))}
) : (
No recent activity
)}
Alert History Recent rate limit threshold violations {alertHistoryLoading ? (
{[1, 2, 3].map((i) => ( ))}
) : alertHistory && alertHistory.length > 0 ? (
{alertHistory.map((alert) => (
{alert.resolved_at ? ( ) : ( )} {alert.metric_type} {format(new Date(alert.created_at), 'PPp')}

{alert.alert_message}

Value: {alert.metric_value.toFixed(2)} Threshold: {alert.threshold_value.toFixed(2)} Window: {alert.time_window_ms / 1000}s
{alert.resolved_at && (

Resolved: {format(new Date(alert.resolved_at), 'PPp')}

)}
{!alert.resolved_at && ( )}
))}
) : (
No alerts triggered yet
)}
!open && setResolvingAlertId(null)} title="Resolve Alert" description="Are you sure you want to mark this alert as resolved? This action cannot be undone." confirmLabel="Resolve" onConfirm={() => { if (resolvingAlertId) { resolveAlert.mutate(resolvingAlertId); setResolvingAlertId(null); } }} />
Alert Configuration Configure thresholds for automated alerts {alertConfigsLoading ? (
{[1, 2, 3].map((i) => ( ))}
) : alertConfigs && alertConfigs.length > 0 ? (
{alertConfigs.map((config) => (
{config.metric_type} updateConfig.mutate({ id: config.id, updates: { enabled } }) } /> {config.enabled ? ( Enabled ) : ( Disabled )}
{ const value = parseFloat(e.target.value); if (!isNaN(value)) { updateConfig.mutate({ id: config.id, updates: { threshold_value: value } }); } }} className="mt-1" />

{config.metric_type === 'block_rate' && 'Value between 0 and 1 (e.g., 0.5 = 50%)'} {config.metric_type === 'total_requests' && 'Number of requests'} {config.metric_type === 'unique_ips' && 'Number of unique IPs'}

{ const value = parseInt(e.target.value); if (!isNaN(value)) { updateConfig.mutate({ id: config.id, updates: { time_window_ms: value } }); } }} className="mt-1" />

Currently: {config.time_window_ms / 1000}s

))}
) : (
No alert configurations found
)}
); }