mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 06:31:13 -05:00
Fix authentication race condition
This commit is contained in:
@@ -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(() => {
|
||||||
fetchItems(activeEntityFilter, activeStatusFilter);
|
if (user) {
|
||||||
}, [activeEntityFilter, activeStatusFilter]);
|
fetchItems(activeEntityFilter, activeStatusFilter);
|
||||||
|
}
|
||||||
|
}, [activeEntityFilter, activeStatusFilter, user]);
|
||||||
|
|
||||||
const handleModerationAction = async (
|
const handleModerationAction = async (
|
||||||
item: ModerationItem,
|
item: ModerationItem,
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user