Fix authentication race condition

This commit is contained in:
gpt-engineer-app[bot]
2025-09-29 19:51:59 +00:00
parent b046ed5977
commit ff52b3c905
2 changed files with 48 additions and 9 deletions

View File

@@ -10,6 +10,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import { useToast } from '@/hooks/use-toast'; import { useToast } from '@/hooks/use-toast';
import { useUserRole } from '@/hooks/useUserRole'; import { useUserRole } from '@/hooks/useUserRole';
import { useAuth } from '@/hooks/useAuth';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { PhotoModal } from './PhotoModal'; import { PhotoModal } from './PhotoModal';
@@ -57,6 +58,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
const [selectedPhotoIndex, setSelectedPhotoIndex] = useState(0); const [selectedPhotoIndex, setSelectedPhotoIndex] = useState(0);
const { toast } = useToast(); const { toast } = useToast();
const { isAdmin, isSuperuser } = useUserRole(); const { isAdmin, isSuperuser } = useUserRole();
const { user } = useAuth();
// Expose refresh method via ref // Expose refresh method via ref
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
@@ -66,6 +68,11 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
}), [activeEntityFilter, activeStatusFilter]); }), [activeEntityFilter, activeStatusFilter]);
const fetchItems = async (entityFilter: EntityFilter = 'all', statusFilter: StatusFilter = 'pending') => { const fetchItems = async (entityFilter: EntityFilter = 'all', statusFilter: StatusFilter = 'pending') => {
if (!user) {
console.log('Skipping fetch - user not authenticated');
return;
}
try { try {
setLoading(true); setLoading(true);
@@ -312,11 +319,16 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
console.log('Photo submissions:', formattedItems.filter(item => item.submission_type === 'photo')); console.log('Photo submissions:', formattedItems.filter(item => item.submission_type === 'photo'));
setItems(formattedItems); setItems(formattedItems);
} catch (error) { } catch (error: any) {
console.error('Error fetching moderation items:', error); console.error('Error fetching moderation items:', error);
console.error('Error details:', {
message: error.message,
code: error.code,
details: error.details
});
toast({ toast({
title: "Error", title: "Error",
description: "Failed to load moderation queue", description: error.message || "Failed to load moderation queue",
variant: "destructive", variant: "destructive",
}); });
} finally { } finally {
@@ -325,8 +337,10 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
}; };
useEffect(() => { useEffect(() => {
if (user) {
fetchItems(activeEntityFilter, activeStatusFilter); fetchItems(activeEntityFilter, activeStatusFilter);
}, [activeEntityFilter, activeStatusFilter]); }
}, [activeEntityFilter, activeStatusFilter, user]);
const handleModerationAction = async ( const handleModerationAction = async (
item: ModerationItem, item: ModerationItem,

View File

@@ -27,38 +27,63 @@ export default function Admin() {
}); });
const fetchStats = useCallback(async () => { const fetchStats = useCallback(async () => {
if (!user) {
console.log('Skipping stats fetch - user not authenticated');
return;
}
try { try {
setStats(prev => ({ ...prev, loading: true })); setStats(prev => ({ ...prev, loading: true }));
// Fetch pending submissions count // Fetch pending submissions count
const { count: pendingCount } = await supabase const { count: pendingCount, error: submissionsError } = await supabase
.from('content_submissions') .from('content_submissions')
.select('*', { count: 'exact', head: true }) .select('*', { count: 'exact', head: true })
.eq('status', 'pending'); .eq('status', 'pending');
if (submissionsError) {
console.error('Error fetching pending submissions:', submissionsError);
throw submissionsError;
}
// Fetch open reports count // Fetch open reports count
const { count: reportsCount } = await supabase const { count: reportsCount, error: reportsError } = await supabase
.from('reports') .from('reports')
.select('*', { count: 'exact', head: true }) .select('*', { count: 'exact', head: true })
.eq('status', 'pending'); .eq('status', 'pending');
if (reportsError) {
console.error('Error fetching reports:', reportsError);
throw reportsError;
}
// Fetch flagged content count (reviews) // Fetch flagged content count (reviews)
const { count: flaggedCount } = await supabase const { count: flaggedCount, error: flaggedError } = await supabase
.from('reviews') .from('reviews')
.select('*', { count: 'exact', head: true }) .select('*', { count: 'exact', head: true })
.eq('moderation_status', 'flagged'); .eq('moderation_status', 'flagged');
if (flaggedError) {
console.error('Error fetching flagged content:', flaggedError);
throw flaggedError;
}
setStats({ setStats({
pendingSubmissions: pendingCount || 0, pendingSubmissions: pendingCount || 0,
openReports: reportsCount || 0, openReports: reportsCount || 0,
flaggedContent: flaggedCount || 0, flaggedContent: flaggedCount || 0,
loading: false, loading: false,
}); });
} catch (error) { } catch (error: any) {
console.error('Error fetching admin stats:', error); 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 })); setStats(prev => ({ ...prev, loading: false }));
} }
}, []); }, [user]);
const handleRefresh = useCallback(() => { const handleRefresh = useCallback(() => {
moderationQueueRef.current?.refresh(); moderationQueueRef.current?.refresh();