mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-24 15:51:13 -05:00
Implement monitoring overview features
Add comprehensive monitoring dashboard scaffolding: - Extend queryKeys with monitoring keys - Create hooks: useCombinedAlerts, useRecentActivity, useDatabaseHealth, useModerationHealth - Build UI components: SystemHealthStatus, CriticalAlertsPanel, MonitoringQuickStats, RecentActivityTimeline, MonitoringNavCards - Create MonitoringOverview page and integrate routing (MonitoringOverview route) - Wire AdminSidebar to include Monitoring navigation - Introduce supporting routing and admin layout hooks/utilities - Align with TanStack Query patterns and plan for auto-refresh and optimistic updates
This commit is contained in:
124
src/pages/admin/MonitoringOverview.tsx
Normal file
124
src/pages/admin/MonitoringOverview.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
import { useState } from 'react';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { AdminLayout } from '@/components/layout/AdminLayout';
|
||||
import { RefreshButton } from '@/components/ui/refresh-button';
|
||||
import { SystemHealthStatus } from '@/components/admin/SystemHealthStatus';
|
||||
import { CriticalAlertsPanel } from '@/components/admin/CriticalAlertsPanel';
|
||||
import { MonitoringQuickStats } from '@/components/admin/MonitoringQuickStats';
|
||||
import { RecentActivityTimeline } from '@/components/admin/RecentActivityTimeline';
|
||||
import { MonitoringNavCards } from '@/components/admin/MonitoringNavCards';
|
||||
import { useSystemHealth } from '@/hooks/useSystemHealth';
|
||||
import { useCombinedAlerts } from '@/hooks/admin/useCombinedAlerts';
|
||||
import { useRecentActivity } from '@/hooks/admin/useRecentActivity';
|
||||
import { useDatabaseHealth } from '@/hooks/admin/useDatabaseHealth';
|
||||
import { useModerationHealth } from '@/hooks/admin/useModerationHealth';
|
||||
import { useRateLimitStats } from '@/hooks/useRateLimitMetrics';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { Label } from '@/components/ui/label';
|
||||
|
||||
export default function MonitoringOverview() {
|
||||
const queryClient = useQueryClient();
|
||||
const [autoRefresh, setAutoRefresh] = useState(true);
|
||||
|
||||
// Fetch all monitoring data
|
||||
const systemHealth = useSystemHealth();
|
||||
const combinedAlerts = useCombinedAlerts();
|
||||
const recentActivity = useRecentActivity(3600000); // 1 hour
|
||||
const dbHealth = useDatabaseHealth();
|
||||
const moderationHealth = useModerationHealth();
|
||||
const rateLimitStats = useRateLimitStats(3600000); // 1 hour
|
||||
|
||||
const isLoading =
|
||||
systemHealth.isLoading ||
|
||||
combinedAlerts.isLoading ||
|
||||
recentActivity.isLoading ||
|
||||
dbHealth.isLoading ||
|
||||
moderationHealth.isLoading ||
|
||||
rateLimitStats.isLoading;
|
||||
|
||||
const handleRefresh = async () => {
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: ['monitoring'],
|
||||
refetchType: 'active'
|
||||
});
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: ['system-health'],
|
||||
refetchType: 'active'
|
||||
});
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: ['system-alerts'],
|
||||
refetchType: 'active'
|
||||
});
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: ['rate-limit'],
|
||||
refetchType: 'active'
|
||||
});
|
||||
};
|
||||
|
||||
// Calculate error count for nav card (from recent activity)
|
||||
const errorCount = recentActivity.data?.filter(e => e.type === 'error').length || 0;
|
||||
|
||||
return (
|
||||
<AdminLayout>
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold tracking-tight">Monitoring Overview</h1>
|
||||
<p className="text-muted-foreground mt-2">Real-time system health, alerts, and activity monitoring</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch
|
||||
id="auto-refresh"
|
||||
checked={autoRefresh}
|
||||
onCheckedChange={setAutoRefresh}
|
||||
/>
|
||||
<Label htmlFor="auto-refresh" className="text-sm cursor-pointer">
|
||||
Auto-refresh
|
||||
</Label>
|
||||
</div>
|
||||
<RefreshButton
|
||||
onRefresh={handleRefresh}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* System Health Status */}
|
||||
<SystemHealthStatus
|
||||
systemHealth={systemHealth.data ?? undefined}
|
||||
dbHealth={dbHealth.data}
|
||||
isLoading={systemHealth.isLoading || dbHealth.isLoading}
|
||||
/>
|
||||
|
||||
{/* Critical Alerts */}
|
||||
<CriticalAlertsPanel
|
||||
alerts={combinedAlerts.data}
|
||||
isLoading={combinedAlerts.isLoading}
|
||||
/>
|
||||
|
||||
{/* Quick Stats Grid */}
|
||||
<MonitoringQuickStats
|
||||
systemHealth={systemHealth.data ?? undefined}
|
||||
rateLimitStats={rateLimitStats.data}
|
||||
moderationHealth={moderationHealth.data}
|
||||
/>
|
||||
|
||||
{/* Recent Activity Timeline */}
|
||||
<RecentActivityTimeline
|
||||
activity={recentActivity.data}
|
||||
isLoading={recentActivity.isLoading}
|
||||
/>
|
||||
|
||||
{/* Quick Navigation Cards */}
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold mb-4">Detailed Dashboards</h2>
|
||||
<MonitoringNavCards
|
||||
errorCount={errorCount}
|
||||
rateLimitCount={rateLimitStats.data?.blocked_requests}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</AdminLayout>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user