diff --git a/src/components/moderation/ModerationQueue.tsx b/src/components/moderation/ModerationQueue.tsx index b9f2b0d9..865dc42f 100644 --- a/src/components/moderation/ModerationQueue.tsx +++ b/src/components/moderation/ModerationQueue.tsx @@ -502,7 +502,8 @@ export const ModerationQueue = forwardRef((props, ref) => { // Handle photo submissions - create photos records when approved if (action === 'approved' && item.type === 'content_submission' && item.submission_type === 'photo') { - console.log('Processing photo submission approval:', item.content); + console.log('🖼️ [PHOTO APPROVAL] Starting photo submission approval'); + console.log('🖼️ [PHOTO APPROVAL] Full item content:', JSON.stringify(item.content, null, 2)); try { // Extract photos array - handle both nested paths @@ -513,31 +514,78 @@ export const ModerationQueue = forwardRef((props, ref) => { item.content?.ride_id ? 'ride' : item.content?.company_id ? 'company' : null); + console.log('🖼️ [PHOTO APPROVAL] Extracted data:', { + photosArray: photosArray, + entityId: entityId, + entityType: entityType, + hasPhotosArray: !!photosArray, + photosCount: photosArray?.length + }); + if (!photosArray || !Array.isArray(photosArray) || photosArray.length === 0) { + console.error('🖼️ [PHOTO APPROVAL] ERROR: No photos found in submission'); throw new Error('No photos found in submission'); } if (!entityId || !entityType) { + console.error('🖼️ [PHOTO APPROVAL] ERROR: Invalid entity information', { entityId, entityType }); throw new Error('Invalid entity information in photo submission'); } - console.log('Creating photo records:', { photosArray, entityId, entityType }); + // Check if photos already exist for this submission (in case of re-approval) + const { data: existingPhotos } = await supabase + .from('photos') + .select('id') + .eq('submission_id', item.id); + + console.log('🖼️ [PHOTO APPROVAL] Existing photos check:', existingPhotos); + + if (existingPhotos && existingPhotos.length > 0) { + console.log('🖼️ [PHOTO APPROVAL] Photos already exist for this submission, skipping creation'); + + // Just update submission status + const { error: updateError } = await supabase + .from('content_submissions') + .update({ + status: 'approved', + reviewer_id: user?.id, + reviewed_at: new Date().toISOString(), + reviewer_notes: moderatorNotes + }) + .eq('id', item.id); + + if (updateError) throw updateError; + + toast({ + title: "Photos Re-Approved", + description: `Photo submission re-approved (${existingPhotos.length} existing photo(s))`, + }); + + fetchItems(activeEntityFilter, activeStatusFilter); + return; + } // Create photo records in the photos table - const photoRecords = photosArray.map((photo, index) => ({ - entity_id: entityId, - entity_type: entityType, - cloudflare_image_id: photo.imageId || photo.cloudflare_image_id, - cloudflare_image_url: photo.url || photo.cloudflare_image_url, - title: photo.title, - caption: photo.caption, - date_taken: photo.date, - order_index: photo.order ?? index, - submission_id: item.id, - submitted_by: item.user_id, - approved_by: user?.id, - approved_at: new Date().toISOString(), - })); + const photoRecords = photosArray.map((photo, index) => { + const record = { + entity_id: entityId, + entity_type: entityType, + cloudflare_image_id: photo.imageId || photo.cloudflare_image_id, + cloudflare_image_url: photo.url || photo.cloudflare_image_url, + title: photo.title, + caption: photo.caption, + date_taken: photo.date, + order_index: photo.order ?? index, + submission_id: item.id, + submitted_by: item.user_id, + approved_by: user?.id, + approved_at: new Date().toISOString(), + }; + console.log('🖼️ [PHOTO APPROVAL] Photo record to insert:', record); + return record; + }); + + console.log('🖼️ [PHOTO APPROVAL] Attempting to insert photo records:', photoRecords); const { data: createdPhotos, error: photoError } = await supabase .from('photos') @@ -545,11 +593,11 @@ export const ModerationQueue = forwardRef((props, ref) => { .select(); if (photoError) { - console.error('Failed to create photo records:', photoError); + console.error('🖼️ [PHOTO APPROVAL] Database error creating photos:', photoError); throw new Error(`Failed to create photos: ${photoError.message}`); } - console.log('Created photo records:', createdPhotos); + console.log('🖼️ [PHOTO APPROVAL] Successfully created photo records:', createdPhotos); // Update submission status const { error: updateError } = await supabase @@ -562,7 +610,12 @@ export const ModerationQueue = forwardRef((props, ref) => { }) .eq('id', item.id); - if (updateError) throw updateError; + if (updateError) { + console.error('🖼️ [PHOTO APPROVAL] Error updating submission:', updateError); + throw updateError; + } + + console.log('🖼️ [PHOTO APPROVAL] ✅ Complete! Created', createdPhotos.length, 'photos'); toast({ title: "Photos Approved", @@ -574,7 +627,8 @@ export const ModerationQueue = forwardRef((props, ref) => { return; } catch (error: any) { - console.error('Error processing photo approval:', error); + console.error('🖼️ [PHOTO APPROVAL] ❌ FATAL ERROR:', error); + console.error('🖼️ [PHOTO APPROVAL] Error details:', error.message, error.code, error.details); throw error; } } diff --git a/src/components/upload/EntityPhotoGallery.tsx b/src/components/upload/EntityPhotoGallery.tsx index 7ef1349d..932cee1a 100644 --- a/src/components/upload/EntityPhotoGallery.tsx +++ b/src/components/upload/EntityPhotoGallery.tsx @@ -39,6 +39,8 @@ export function EntityPhotoGallery({ const fetchPhotos = async () => { try { + console.log('📷 [FETCH PHOTOS] Starting fetch for:', { entityId, entityType }); + // Fetch photos directly from the photos table const { data: photoData, error } = await supabase .from('photos') @@ -48,6 +50,8 @@ export function EntityPhotoGallery({ .order('order_index', { ascending: true }) .order('created_at', { ascending: false }); + console.log('📷 [FETCH PHOTOS] Query result:', { photoData, error, count: photoData?.length }); + if (error) throw error; // Map to Photo interface @@ -60,9 +64,10 @@ export function EntityPhotoGallery({ created_at: photo.created_at, })) || []; + console.log('📷 [FETCH PHOTOS] Mapped photos:', mappedPhotos); setPhotos(mappedPhotos); } catch (error) { - console.error('Error fetching photos:', error); + console.error('📷 [FETCH PHOTOS] Error:', error); } finally { setLoading(false); }