diff --git a/src/components/moderation/ModerationQueue.tsx b/src/components/moderation/ModerationQueue.tsx index aaf4c14c..b4319a19 100644 --- a/src/components/moderation/ModerationQueue.tsx +++ b/src/components/moderation/ModerationQueue.tsx @@ -617,6 +617,67 @@ export const ModerationQueue = forwardRef((props, ref) => { } } + // Check if this submission has submission_items that need processing + if (item.type === 'content_submission') { + const { data: submissionItems, error: itemsError } = await supabase + .from('submission_items') + .select('id, status') + .eq('submission_id', item.id) + .eq('status', 'pending'); + + if (!itemsError && submissionItems && submissionItems.length > 0) { + console.log(`Found ${submissionItems.length} pending submission items for ${item.id}`); + + if (action === 'approved') { + // Call the edge function to process all items + const { data: approvalData, error: approvalError } = await supabase.functions.invoke( + 'process-selective-approval', + { + body: { + itemIds: submissionItems.map(i => i.id), + userId: user?.id, + submissionId: item.id + } + } + ); + + if (approvalError) { + throw new Error(`Failed to process submission items: ${approvalError.message}`); + } + + console.log('Submission items processed successfully:', approvalData); + + toast({ + title: "Submission Approved", + description: `Successfully processed ${submissionItems.length} item(s)`, + }); + + // Refresh and return early since edge function already updated parent + fetchItems(activeEntityFilter, activeStatusFilter); + return; + } else if (action === 'rejected') { + // Cascade rejection to all pending items + console.log('Cascading rejection to submission items'); + const { error: rejectError } = await supabase + .from('submission_items') + .update({ + status: 'rejected', + rejection_reason: moderatorNotes || 'Parent submission rejected', + updated_at: new Date().toISOString() + }) + .eq('submission_id', item.id) + .eq('status', 'pending'); + + if (rejectError) { + console.error('Failed to cascade rejection:', rejectError); + // Don't fail the whole operation, just log it + } else { + console.log('Successfully cascaded rejection to submission items'); + } + } + } + } + // Standard moderation flow for other items const table = item.type === 'review' ? 'reviews' : 'content_submissions'; const statusField = item.type === 'review' ? 'moderation_status' : 'status'; diff --git a/supabase/functions/process-selective-approval/index.ts b/supabase/functions/process-selective-approval/index.ts index 45bdc918..ae0d7790 100644 --- a/supabase/functions/process-selective-approval/index.ts +++ b/supabase/functions/process-selective-approval/index.ts @@ -197,37 +197,88 @@ function resolveDependencies(data: any, dependencyMap: Map): any } async function createPark(supabase: any, data: any): Promise { - const { data: park, error } = await supabase - .from('parks') - .insert(data) - .select('id') - .single(); + // Check if this is an edit (has park_id) or a new creation + if (data.park_id) { + console.log(`Updating existing park ${data.park_id}`); + const parkId = data.park_id; + delete data.park_id; // Remove ID from update data + + const { error } = await supabase + .from('parks') + .update(data) + .eq('id', parkId); - if (error) throw new Error(`Failed to create park: ${error.message}`); - return park.id; + if (error) throw new Error(`Failed to update park: ${error.message}`); + return parkId; + } else { + console.log('Creating new park'); + const { data: park, error } = await supabase + .from('parks') + .insert(data) + .select('id') + .single(); + + if (error) throw new Error(`Failed to create park: ${error.message}`); + return park.id; + } } async function createRide(supabase: any, data: any): Promise { - const { data: ride, error } = await supabase - .from('rides') - .insert(data) - .select('id') - .single(); + // Check if this is an edit (has ride_id) or a new creation + if (data.ride_id) { + console.log(`Updating existing ride ${data.ride_id}`); + const rideId = data.ride_id; + delete data.ride_id; // Remove ID from update data + + const { error } = await supabase + .from('rides') + .update(data) + .eq('id', rideId); - if (error) throw new Error(`Failed to create ride: ${error.message}`); - return ride.id; + if (error) throw new Error(`Failed to update ride: ${error.message}`); + return rideId; + } else { + console.log('Creating new ride'); + const { data: ride, error } = await supabase + .from('rides') + .insert(data) + .select('id') + .single(); + + if (error) throw new Error(`Failed to create ride: ${error.message}`); + return ride.id; + } } async function createCompany(supabase: any, data: any, companyType: string): Promise { - const companyData = { ...data, company_type: companyType }; - const { data: company, error } = await supabase - .from('companies') - .insert(companyData) - .select('id') - .single(); + // Check if this is an edit (has company_id or id) or a new creation + const companyId = data.company_id || data.id; + + if (companyId) { + console.log(`Updating existing company ${companyId}`); + const updateData = { ...data, company_type: companyType }; + delete updateData.company_id; + delete updateData.id; // Remove ID from update data + + const { error } = await supabase + .from('companies') + .update(updateData) + .eq('id', companyId); - if (error) throw new Error(`Failed to create company: ${error.message}`); - return company.id; + if (error) throw new Error(`Failed to update company: ${error.message}`); + return companyId; + } else { + console.log('Creating new company'); + const companyData = { ...data, company_type: companyType }; + const { data: company, error } = await supabase + .from('companies') + .insert(companyData) + .select('id') + .single(); + + if (error) throw new Error(`Failed to create company: ${error.message}`); + return company.id; + } } async function createRideModel(supabase: any, data: any): Promise {