mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 11:31:11 -05:00
feat: Cascade moderation actions to submission items
This commit is contained in:
@@ -617,6 +617,67 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((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
|
// Standard moderation flow for other items
|
||||||
const table = item.type === 'review' ? 'reviews' : 'content_submissions';
|
const table = item.type === 'review' ? 'reviews' : 'content_submissions';
|
||||||
const statusField = item.type === 'review' ? 'moderation_status' : 'status';
|
const statusField = item.type === 'review' ? 'moderation_status' : 'status';
|
||||||
|
|||||||
@@ -197,37 +197,88 @@ function resolveDependencies(data: any, dependencyMap: Map<string, string>): any
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function createPark(supabase: any, data: any): Promise<string> {
|
async function createPark(supabase: any, data: any): Promise<string> {
|
||||||
const { data: park, error } = await supabase
|
// Check if this is an edit (has park_id) or a new creation
|
||||||
.from('parks')
|
if (data.park_id) {
|
||||||
.insert(data)
|
console.log(`Updating existing park ${data.park_id}`);
|
||||||
.select('id')
|
const parkId = data.park_id;
|
||||||
.single();
|
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}`);
|
if (error) throw new Error(`Failed to update park: ${error.message}`);
|
||||||
return park.id;
|
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<string> {
|
async function createRide(supabase: any, data: any): Promise<string> {
|
||||||
const { data: ride, error } = await supabase
|
// Check if this is an edit (has ride_id) or a new creation
|
||||||
.from('rides')
|
if (data.ride_id) {
|
||||||
.insert(data)
|
console.log(`Updating existing ride ${data.ride_id}`);
|
||||||
.select('id')
|
const rideId = data.ride_id;
|
||||||
.single();
|
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}`);
|
if (error) throw new Error(`Failed to update ride: ${error.message}`);
|
||||||
return ride.id;
|
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<string> {
|
async function createCompany(supabase: any, data: any, companyType: string): Promise<string> {
|
||||||
const companyData = { ...data, company_type: companyType };
|
// Check if this is an edit (has company_id or id) or a new creation
|
||||||
const { data: company, error } = await supabase
|
const companyId = data.company_id || data.id;
|
||||||
.from('companies')
|
|
||||||
.insert(companyData)
|
if (companyId) {
|
||||||
.select('id')
|
console.log(`Updating existing company ${companyId}`);
|
||||||
.single();
|
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}`);
|
if (error) throw new Error(`Failed to update company: ${error.message}`);
|
||||||
return company.id;
|
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<string> {
|
async function createRideModel(supabase: any, data: any): Promise<string> {
|
||||||
|
|||||||
Reference in New Issue
Block a user