mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 20:31:14 -05:00
Implement real-time features
This commit is contained in:
@@ -11,6 +11,7 @@ import { ReportsQueue } from '@/components/moderation/ReportsQueue';
|
||||
import { UserManagement } from '@/components/admin/UserManagement';
|
||||
import { AdminHeader } from '@/components/layout/AdminHeader';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { useRealtimeModerationStats } from '@/hooks/useRealtimeModerationStats';
|
||||
|
||||
export default function Admin() {
|
||||
const { user, loading: authLoading } = useAuth();
|
||||
@@ -18,76 +19,19 @@ export default function Admin() {
|
||||
const navigate = useNavigate();
|
||||
const moderationQueueRef = useRef<ModerationQueueRef>(null);
|
||||
|
||||
// State for dashboard stats
|
||||
const [stats, setStats] = useState({
|
||||
pendingSubmissions: 0,
|
||||
openReports: 0,
|
||||
flaggedContent: 0,
|
||||
loading: true,
|
||||
// Use realtime stats hook for live updates
|
||||
const { stats: realtimeStats, refresh: refreshStats } = useRealtimeModerationStats({
|
||||
onStatsChange: (newStats) => {
|
||||
console.log('Stats updated in real-time:', newStats);
|
||||
},
|
||||
enabled: !!user && !authLoading && !roleLoading && isModerator(),
|
||||
});
|
||||
|
||||
const [isFetching, setIsFetching] = useState(false);
|
||||
|
||||
const fetchStats = useCallback(async () => {
|
||||
if (!user || isFetching) {
|
||||
console.log('Skipping stats fetch - user not authenticated or already fetching');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsFetching(true);
|
||||
try {
|
||||
setStats(prev => ({ ...prev, loading: true }));
|
||||
|
||||
// Fetch pending submissions count
|
||||
const { count: pendingCount, error: submissionsError } = await supabase
|
||||
.from('content_submissions')
|
||||
.select('*', { count: 'exact', head: true })
|
||||
.eq('status', 'pending');
|
||||
|
||||
if (submissionsError) {
|
||||
console.error('Error fetching pending submissions:', submissionsError);
|
||||
throw submissionsError;
|
||||
}
|
||||
|
||||
// Fetch open reports count
|
||||
const { count: reportsCount, error: reportsError } = await supabase
|
||||
.from('reports')
|
||||
.select('*', { count: 'exact', head: true })
|
||||
.eq('status', 'pending');
|
||||
|
||||
if (reportsError) {
|
||||
console.error('Error fetching reports:', reportsError);
|
||||
throw reportsError;
|
||||
}
|
||||
|
||||
// Fetch flagged content count (reviews)
|
||||
const { count: flaggedCount, error: flaggedError } = await supabase
|
||||
.from('reviews')
|
||||
.select('*', { count: 'exact', head: true })
|
||||
.eq('moderation_status', 'flagged');
|
||||
|
||||
if (flaggedError) {
|
||||
console.error('Error fetching flagged content:', flaggedError);
|
||||
throw flaggedError;
|
||||
}
|
||||
|
||||
setStats({
|
||||
pendingSubmissions: pendingCount || 0,
|
||||
openReports: reportsCount || 0,
|
||||
flaggedContent: flaggedCount || 0,
|
||||
loading: false,
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('Error fetching admin stats:', error);
|
||||
console.error('Error details:', {
|
||||
message: error.message,
|
||||
code: error.code,
|
||||
details: error.details
|
||||
});
|
||||
setStats(prev => ({ ...prev, loading: false }));
|
||||
} finally {
|
||||
setIsFetching(false);
|
||||
}
|
||||
}, []);
|
||||
refreshStats();
|
||||
}, [refreshStats]);
|
||||
|
||||
const handleRefresh = useCallback(() => {
|
||||
moderationQueueRef.current?.refresh();
|
||||
@@ -105,11 +49,8 @@ export default function Admin() {
|
||||
navigate('/');
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch stats when user is authenticated and authorized
|
||||
fetchStats();
|
||||
}
|
||||
}, [user, authLoading, roleLoading, navigate]);
|
||||
}, [user, authLoading, roleLoading, navigate, isModerator]);
|
||||
|
||||
if (authLoading || roleLoading) {
|
||||
return (
|
||||
@@ -146,11 +87,7 @@ export default function Admin() {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">
|
||||
{stats.loading ? (
|
||||
<span className="animate-pulse">--</span>
|
||||
) : (
|
||||
stats.pendingSubmissions
|
||||
)}
|
||||
{realtimeStats.pendingSubmissions}
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Content submissions awaiting moderation
|
||||
@@ -165,11 +102,7 @@ export default function Admin() {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">
|
||||
{stats.loading ? (
|
||||
<span className="animate-pulse">--</span>
|
||||
) : (
|
||||
stats.openReports
|
||||
)}
|
||||
{realtimeStats.openReports}
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
User reports to review
|
||||
@@ -184,11 +117,7 @@ export default function Admin() {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">
|
||||
{stats.loading ? (
|
||||
<span className="animate-pulse">--</span>
|
||||
) : (
|
||||
stats.flaggedContent
|
||||
)}
|
||||
{realtimeStats.flaggedContent}
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Auto-flagged items
|
||||
|
||||
Reference in New Issue
Block a user