diff --git a/src/components/moderation/ModerationQueue.tsx b/src/components/moderation/ModerationQueue.tsx index cb1b0713..f9f88873 100644 --- a/src/components/moderation/ModerationQueue.tsx +++ b/src/components/moderation/ModerationQueue.tsx @@ -398,7 +398,17 @@ export const ModerationQueue = forwardRef((props, ref) => { const handleDeleteSubmission = async (item: ModerationItem) => { if (item.type !== 'content_submission') return; + // Prevent duplicate calls + if (actionLoading === item.id) { + console.log('Deletion already in progress for:', item.id); + return; + } + setActionLoading(item.id); + + // Remove item from UI immediately to prevent flickering + setItems(prev => prev.filter(i => i.id !== item.id)); + try { console.log('Starting deletion process for submission:', item.id); @@ -419,21 +429,34 @@ export const ModerationQueue = forwardRef((props, ref) => { // Try to extract image ID from various URL formats let imageId = ''; + // UUID pattern: 8-4-4-4-12 characters + const uuidRegex = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i; + // If it's already just an ID - if (photo.url.match(/^[a-f0-9-]{36}$/)) { + if (uuidRegex.test(photo.url)) { imageId = photo.url; } else { - // Extract from URL path - const urlParts = photo.url.split('/'); - const lastPart = urlParts[urlParts.length - 1]; - if (lastPart && lastPart.match(/^[a-f0-9-]{36}$/)) { - imageId = lastPart; + // Extract from Cloudflare image delivery URL format: + // https://imagedelivery.net/X-2-mmiWukWxvAQQ2_o-7Q/IMAGE_ID/public + const cloudflareMatch = photo.url.match(/imagedelivery\.net\/[^\/]+\/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/i); + if (cloudflareMatch) { + imageId = cloudflareMatch[1]; + } else { + // Fallback: Extract from URL path + const urlParts = photo.url.split('/'); + for (const part of urlParts) { + if (uuidRegex.test(part)) { + imageId = part; + break; + } + } } } if (imageId) { photoIds.push(imageId); validImageIds.push(imageId); + console.log('Successfully extracted image ID:', imageId, 'from URL:', photo.url); } else { console.warn('Could not extract valid image ID from URL:', photo.url); skippedPhotos.push(photo.url); @@ -511,9 +534,17 @@ export const ModerationQueue = forwardRef((props, ref) => { }); // Remove item from the current view - setItems(prev => prev.filter(i => i.id !== item.id)); + // Item was already removed at the start for immediate UI feedback } catch (error) { console.error('Error deleting submission:', error); + + // Restore item to list on error since we removed it optimistically + setItems(prev => { + // Avoid duplicates + if (prev.some(i => i.id === item.id)) return prev; + return [...prev, item]; + }); + toast({ title: "Error", description: "Failed to delete submission",