Fix: Add dashboard widget for flow violations

This commit is contained in:
gpt-engineer-app[bot]
2025-10-06 17:01:41 +00:00
parent 124fe5e76e
commit 3210147654
3 changed files with 117 additions and 2 deletions

View File

@@ -1,6 +1,6 @@
import { useRef, useEffect, useCallback, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { FileText, Flag, AlertCircle, Activity } from 'lucide-react';
import { FileText, Flag, AlertCircle, Activity, ShieldAlert } from 'lucide-react';
import { useUserRole } from '@/hooks/useUserRole';
import { useAuth } from '@/hooks/useAuth';
import { Card, CardContent } from '@/components/ui/card';
@@ -12,6 +12,8 @@ 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 '@/integrations/supabase/client';
import { Alert, AlertDescription } from '@/components/ui/alert';
export default function AdminDashboard() {
const { user, loading: authLoading } = useAuth();
@@ -19,6 +21,7 @@ export default function AdminDashboard() {
const navigate = useNavigate();
const [isRefreshing, setIsRefreshing] = useState(false);
const [activeTab, setActiveTab] = useState('moderation');
const [suspiciousVersionsCount, setSuspiciousVersionsCount] = useState<number>(0);
const moderationQueueRef = useRef<ModerationQueueRef>(null);
const reportsQueueRef = useRef<any>(null);
@@ -38,9 +41,28 @@ export default function AdminDashboard() {
pollingInterval: pollInterval,
});
// Check for suspicious versions (bypassed submission flow)
const checkSuspiciousVersions = useCallback(async () => {
if (!user || !isModerator()) return;
const { count, error } = await supabase
.from('entity_versions')
.select('*', { count: 'exact', head: true })
.is('changed_by', null);
if (!error && count !== null) {
setSuspiciousVersionsCount(count);
}
}, [user, isModerator]);
useEffect(() => {
checkSuspiciousVersions();
}, [checkSuspiciousVersions]);
const handleRefresh = useCallback(async () => {
setIsRefreshing(true);
await refreshStats();
await checkSuspiciousVersions();
// Refresh active tab's content
switch (activeTab) {
@@ -56,7 +78,7 @@ export default function AdminDashboard() {
}
setTimeout(() => setIsRefreshing(false), 500);
}, [refreshStats, activeTab]);
}, [refreshStats, checkSuspiciousVersions, activeTab]);
const handleStatCardClick = (cardType: 'submissions' | 'reports' | 'flagged') => {
switch (cardType) {
@@ -143,6 +165,17 @@ export default function AdminDashboard() {
</p>
</div>
{/* Security Warning for Suspicious Versions */}
{suspiciousVersionsCount > 0 && (
<Alert variant="destructive" className="border-red-500/50 bg-red-500/10">
<ShieldAlert className="h-5 w-5" />
<AlertDescription className="ml-2">
<strong>Security Alert:</strong> {suspiciousVersionsCount} entity version{suspiciousVersionsCount !== 1 ? 's' : ''} detected without user attribution.
This may indicate submission flow bypass. Check admin audit logs for details.
</AlertDescription>
</Alert>
)}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{statCards.map((card) => {
const Icon = card.icon;