import { useRef, useEffect, useCallback, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { FileText, Flag, AlertCircle, Activity, ShieldAlert } from 'lucide-react'; import { useUserRole } from '@/hooks/useUserRole'; import { useAuth } from '@/hooks/useAuth'; import { useRequireMFA } from '@/hooks/useRequireMFA'; import { MFAGuard } from '@/components/auth/MFAGuard'; import { Card, CardContent } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; import { AdminLayout } from '@/components/layout/AdminLayout'; import { ModerationQueue, ModerationQueueRef } from '@/components/moderation/ModerationQueue'; import { ReportsQueue } from '@/components/moderation/ReportsQueue'; import { RecentActivity } from '@/components/moderation/RecentActivity'; import { useModerationStats } from '@/hooks/useModerationStats'; import { useAdminSettings } from '@/hooks/useAdminSettings'; import { supabase } from '@/lib/supabaseClient'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { Skeleton } from '@/components/ui/skeleton'; import { QueueSkeleton } from '@/components/moderation/QueueSkeleton'; import { useDocumentTitle } from '@/hooks/useDocumentTitle'; export default function AdminDashboard() { useDocumentTitle('Dashboard - Admin'); const { user, loading: authLoading } = useAuth(); const { isModerator, loading: roleLoading } = useUserRole(); const { needsEnrollment, loading: mfaLoading } = useRequireMFA(); const navigate = useNavigate(); const [isRefreshing, setIsRefreshing] = useState(false); const [activeTab, setActiveTab] = useState('moderation'); const [suspiciousVersionsCount, setSuspiciousVersionsCount] = useState(0); const moderationQueueRef = useRef(null); const reportsQueueRef = useRef(null); const recentActivityRef = useRef(null); const { getAdminPanelRefreshMode, getAdminPanelPollInterval, } = useAdminSettings(); const refreshMode = getAdminPanelRefreshMode(); const pollInterval = getAdminPanelPollInterval(); const { stats, refresh: refreshStats, optimisticallyUpdateStats, lastUpdated } = useModerationStats({ enabled: !!user && !authLoading && !roleLoading && isModerator(), pollingEnabled: refreshMode === 'auto', pollingInterval: pollInterval, }); // Check for suspicious versions (bypassed submission flow) const checkSuspiciousVersions = useCallback(async () => { if (!user || !isModerator()) return; // Query all version tables for suspicious entries (no changed_by) const queries = [ supabase.from('park_versions').select('*', { count: 'exact', head: true }).is('created_by', null), supabase.from('ride_versions').select('*', { count: 'exact', head: true }).is('created_by', null), supabase.from('company_versions').select('*', { count: 'exact', head: true }).is('created_by', null), supabase.from('ride_model_versions').select('*', { count: 'exact', head: true }).is('created_by', null), ]; const results = await Promise.all(queries); const totalCount = results.reduce((sum, result) => sum + (result.count || 0), 0); setSuspiciousVersionsCount(totalCount); }, [user, isModerator]); useEffect(() => { checkSuspiciousVersions(); }, [checkSuspiciousVersions]); const handleRefresh = useCallback(async () => { setIsRefreshing(true); await refreshStats(); await checkSuspiciousVersions(); // Refresh active tab's content switch (activeTab) { case 'moderation': moderationQueueRef.current?.refresh(); break; case 'reports': reportsQueueRef.current?.refresh(); break; case 'activity': recentActivityRef.current?.refresh(); break; } setTimeout(() => setIsRefreshing(false), 500); }, [refreshStats, checkSuspiciousVersions, activeTab]); const handleStatCardClick = (cardType: 'submissions' | 'reports' | 'flagged') => { switch (cardType) { case 'submissions': setActiveTab('moderation'); break; case 'reports': setActiveTab('reports'); break; case 'flagged': setActiveTab('moderation'); break; } }; useEffect(() => { if (!authLoading && !roleLoading) { if (!user) { navigate('/auth'); return; } if (!isModerator()) { navigate('/'); return; } } }, [user, authLoading, roleLoading, navigate, isModerator]); if (authLoading || roleLoading || mfaLoading) { return (

Admin Dashboard

Central hub for all moderation activity

{/* Skeleton for stat cards */}
{[1, 2, 3].map((i) => (
))}
{/* Skeleton for tabs */}
); } if (!user || !isModerator()) { return null; } const statCards = [ { label: 'Pending Submissions', value: stats.pendingSubmissions, icon: FileText, color: 'amber', type: 'submissions' as const, }, { label: 'Open Reports', value: stats.openReports, icon: Flag, color: 'red', type: 'reports' as const, }, { label: 'Flagged Content', value: stats.flaggedContent, icon: AlertCircle, color: 'orange', type: 'flagged' as const, }, ]; return (

Admin Dashboard

Central hub for all moderation activity

{/* Security Warning for Suspicious Versions */} {suspiciousVersionsCount > 0 && ( Security Alert: {suspiciousVersionsCount} entity version{suspiciousVersionsCount !== 1 ? 's' : ''} detected without user attribution. This may indicate submission flow bypass. Check admin audit logs for details. )}
{statCards.map((card) => { const Icon = card.icon; const colorClasses = { amber: { card: 'hover:border-amber-500/50', bg: 'bg-amber-500/10', icon: 'text-amber-600 dark:text-amber-400', }, red: { card: 'hover:border-red-500/50', bg: 'bg-red-500/10', icon: 'text-red-600 dark:text-red-400', }, orange: { card: 'hover:border-orange-500/50', bg: 'bg-orange-500/10', icon: 'text-orange-600 dark:text-orange-400', }, }; const colors = colorClasses[card.color as keyof typeof colorClasses]; return ( handleStatCardClick(card.type)} >

{card.label}

{card.value}
); })}
Moderation Queue Queue {stats.pendingSubmissions > 0 && ( {stats.pendingSubmissions} )} Reports Reports {stats.openReports > 0 && ( {stats.openReports} )} Recent Activity Activity
); }