diff --git a/src/components/moderation/ModerationQueue.tsx b/src/components/moderation/ModerationQueue.tsx index 4a9e4019..be130e3e 100644 --- a/src/components/moderation/ModerationQueue.tsx +++ b/src/components/moderation/ModerationQueue.tsx @@ -1213,7 +1213,9 @@ export const ModerationQueue = forwardRef((props, ref) => { ) : (item.submission_type === 'manufacturer' || item.submission_type === 'designer' || item.submission_type === 'operator' || - item.submission_type === 'property_owner') ? ( + item.submission_type === 'property_owner' || + item.submission_type === 'park' || + item.submission_type === 'ride') ? (
@@ -1224,114 +1226,8 @@ export const ModerationQueue = forwardRef((props, ref) => {
-
- {/* Basic Information */} -
-
- Name: - {item.content.name} -
-
- Slug: - {item.content.slug} -
- {item.content.person_type && ( -
- Type: - {item.content.person_type} -
- )} - {item.content.description && ( -
- Description: -

{item.content.description}

-
- )} - {item.content.website_url && ( -
- Website: - - {item.content.website_url} - -
- )} - {item.content.founded_year && ( -
- Founded: - {item.content.founded_year} -
- )} - {item.content.headquarters_location && ( -
- Headquarters: - {item.content.headquarters_location} -
- )} -
- - {/* Images */} - {item.content.images?.uploaded && item.content.images.uploaded.length > 0 && ( -
-
Images ({item.content.images.uploaded.length}):
-
- {item.content.images.uploaded.map((image: any, index: number) => ( -
-
{ - setSelectedPhotos(item.content.images.uploaded.map((img: any, i: number) => ({ - id: `${item.id}-${i}`, - url: img.url, - filename: `Image ${i + 1}`, - caption: img.caption - }))); - setSelectedPhotoIndex(index); - setPhotoModalOpen(true); - }}> - {image.caption { - console.error('Failed to load company image:', image.url); - (e.target as HTMLImageElement).style.display = 'none'; - }} - /> -
- -
-
- {image.caption && ( -

{image.caption}

- )} -
- ))} -
- - {/* Image Role Assignments */} - {(item.content.images.banner || item.content.images.card) && ( -
-
Image Assignments:
- {item.content.images.banner !== undefined && ( -
- Banner: - - {item.content.images.banner === null ? 'None' : `Image ${item.content.images.banner + 1}`} - -
- )} - {item.content.images.card !== undefined && ( -
- Card: - - {item.content.images.card === null ? 'None' : `Image ${item.content.images.card + 1}`} - -
- )} -
- )} -
- )} +
+ This is a complex submission with items. Click "Review Items" to see details.
) : ( diff --git a/src/lib/companyHelpers.ts b/src/lib/companyHelpers.ts index 77871e32..50436445 100644 --- a/src/lib/companyHelpers.ts +++ b/src/lib/companyHelpers.ts @@ -28,14 +28,29 @@ export async function submitCompanyCreation( }; } - // All users submit for moderation - const { error } = await supabase + // Create the main submission record + const { data: submissionData, error: submissionError } = await supabase .from('content_submissions') - .insert([{ + .insert({ user_id: userId, - submission_type: companyType, // Use entity-specific type: 'manufacturer', 'designer', 'operator', or 'property_owner' + submission_type: companyType, content: { - action: 'create', + action: 'create' + }, + status: 'pending' + }) + .select() + .single(); + + if (submissionError) throw submissionError; + + // Create the submission item with actual company data + const { error: itemError } = await supabase + .from('submission_items') + .insert({ + submission_id: submissionData.id, + item_type: companyType, + item_data: { name: data.name, slug: data.slug, description: data.description, @@ -44,13 +59,15 @@ export async function submitCompanyCreation( founded_year: data.founded_year, headquarters_location: data.headquarters_location, company_type: companyType, - images: processedImages as any // Include uploaded image assignments in submission - } as any, - status: 'pending' - }]); + images: processedImages as any + }, + status: 'pending', + order_index: 0 + }); - if (error) throw error; - return { submitted: true }; + if (itemError) throw itemError; + + return { submitted: true, submissionId: submissionData.id }; } export async function submitCompanyUpdate( @@ -78,14 +95,30 @@ export async function submitCompanyUpdate( }; } - // All users submit for moderation - const { error } = await supabase + // Create the main submission record + const { data: submissionData, error: submissionError } = await supabase .from('content_submissions') - .insert([{ + .insert({ user_id: userId, - submission_type: existingCompany.company_type, // Use entity-specific type from existing company + submission_type: existingCompany.company_type, content: { action: 'edit', + company_id: companyId + }, + status: 'pending' + }) + .select() + .single(); + + if (submissionError) throw submissionError; + + // Create the submission item with actual company data + const { error: itemError } = await supabase + .from('submission_items') + .insert({ + submission_id: submissionData.id, + item_type: existingCompany.company_type, + item_data: { company_id: companyId, name: data.name, slug: data.slug, @@ -94,11 +127,13 @@ export async function submitCompanyUpdate( website_url: data.website_url, founded_year: data.founded_year, headquarters_location: data.headquarters_location, - images: processedImages as any // Include uploaded image role assignments in submission - } as any, - status: 'pending' - }]); + images: processedImages as any + }, + status: 'pending', + order_index: 0 + }); - if (error) throw error; - return { submitted: true }; + if (itemError) throw itemError; + + return { submitted: true, submissionId: submissionData.id }; } diff --git a/src/lib/entitySubmissionHelpers.ts b/src/lib/entitySubmissionHelpers.ts new file mode 100644 index 00000000..566d15bd --- /dev/null +++ b/src/lib/entitySubmissionHelpers.ts @@ -0,0 +1,262 @@ +import { supabase } from '@/integrations/supabase/client'; +import { ImageAssignments } from '@/components/upload/EntityMultiImageUploader'; +import { uploadPendingImages } from './imageUploadHelper'; + +export interface ParkFormData { + name: string; + slug: string; + description?: string; + park_type: string; + status: string; + opening_date?: string; + closing_date?: string; + website_url?: string; + phone?: string; + email?: string; + operator_id?: string; + property_owner_id?: string; + location_id?: string; + images?: ImageAssignments; + banner_image_url?: string; + banner_image_id?: string; + card_image_url?: string; + card_image_id?: string; +} + +export interface RideFormData { + name: string; + slug: string; + description?: string; + category: string; + status: string; + park_id: string; + manufacturer_id?: string; + designer_id?: string; + ride_model_id?: string; + opening_date?: string; + closing_date?: string; + max_speed_kmh?: number; + max_height_meters?: number; + length_meters?: number; + duration_seconds?: number; + capacity_per_hour?: number; + height_requirement?: number; + age_requirement?: number; + inversions?: number; + drop_height_meters?: number; + max_g_force?: number; + intensity_level?: string; + coaster_type?: string; + seating_type?: string; + ride_sub_type?: string; + coaster_stats?: any; + technical_specs?: any; + former_names?: any; + images?: ImageAssignments; + banner_image_url?: string; + banner_image_id?: string; + card_image_url?: string; + card_image_id?: string; +} + +export async function submitParkCreation( + data: ParkFormData, + userId: string +) { + // Upload any pending local images first + let processedImages = data.images; + if (data.images?.uploaded && data.images.uploaded.length > 0) { + const uploadedImages = await uploadPendingImages(data.images.uploaded); + processedImages = { + ...data.images, + uploaded: uploadedImages + }; + } + + // Create the main submission record + const { data: submissionData, error: submissionError } = await supabase + .from('content_submissions') + .insert({ + user_id: userId, + submission_type: 'park', + content: { + action: 'create' + }, + status: 'pending' + }) + .select() + .single(); + + if (submissionError) throw submissionError; + + // Create the submission item with actual park data + const { error: itemError } = await supabase + .from('submission_items') + .insert({ + submission_id: submissionData.id, + item_type: 'park', + item_data: { + ...data, + images: processedImages as any + }, + status: 'pending', + order_index: 0 + }); + + if (itemError) throw itemError; + + return { submitted: true, submissionId: submissionData.id }; +} + +export async function submitParkUpdate( + parkId: string, + data: ParkFormData, + userId: string +) { + // Upload any pending local images first + let processedImages = data.images; + if (data.images?.uploaded && data.images.uploaded.length > 0) { + const uploadedImages = await uploadPendingImages(data.images.uploaded); + processedImages = { + ...data.images, + uploaded: uploadedImages + }; + } + + // Create the main submission record + const { data: submissionData, error: submissionError } = await supabase + .from('content_submissions') + .insert({ + user_id: userId, + submission_type: 'park', + content: { + action: 'edit', + park_id: parkId + }, + status: 'pending' + }) + .select() + .single(); + + if (submissionError) throw submissionError; + + // Create the submission item with actual park data + const { error: itemError } = await supabase + .from('submission_items') + .insert({ + submission_id: submissionData.id, + item_type: 'park', + item_data: { + ...data, + park_id: parkId, + images: processedImages as any + }, + status: 'pending', + order_index: 0 + }); + + if (itemError) throw itemError; + + return { submitted: true, submissionId: submissionData.id }; +} + +export async function submitRideCreation( + data: RideFormData, + userId: string +) { + // Upload any pending local images first + let processedImages = data.images; + if (data.images?.uploaded && data.images.uploaded.length > 0) { + const uploadedImages = await uploadPendingImages(data.images.uploaded); + processedImages = { + ...data.images, + uploaded: uploadedImages + }; + } + + // Create the main submission record + const { data: submissionData, error: submissionError } = await supabase + .from('content_submissions') + .insert({ + user_id: userId, + submission_type: 'ride', + content: { + action: 'create' + }, + status: 'pending' + }) + .select() + .single(); + + if (submissionError) throw submissionError; + + // Create the submission item with actual ride data + const { error: itemError } = await supabase + .from('submission_items') + .insert({ + submission_id: submissionData.id, + item_type: 'ride', + item_data: { + ...data, + images: processedImages as any + }, + status: 'pending', + order_index: 0 + }); + + if (itemError) throw itemError; + + return { submitted: true, submissionId: submissionData.id }; +} + +export async function submitRideUpdate( + rideId: string, + data: RideFormData, + userId: string +) { + // Upload any pending local images first + let processedImages = data.images; + if (data.images?.uploaded && data.images.uploaded.length > 0) { + const uploadedImages = await uploadPendingImages(data.images.uploaded); + processedImages = { + ...data.images, + uploaded: uploadedImages + }; + } + + // Create the main submission record + const { data: submissionData, error: submissionError } = await supabase + .from('content_submissions') + .insert({ + user_id: userId, + submission_type: 'ride', + content: { + action: 'edit', + ride_id: rideId + }, + status: 'pending' + }) + .select() + .single(); + + if (submissionError) throw submissionError; + + // Create the submission item with actual ride data + const { error: itemError } = await supabase + .from('submission_items') + .insert({ + submission_id: submissionData.id, + item_type: 'ride', + item_data: { + ...data, + ride_id: rideId, + images: processedImages as any + }, + status: 'pending', + order_index: 0 + }); + + if (itemError) throw itemError; + + return { submitted: true, submissionId: submissionData.id }; +} diff --git a/src/pages/ParkDetail.tsx b/src/pages/ParkDetail.tsx index b6be337b..eb11220a 100644 --- a/src/pages/ParkDetail.tsx +++ b/src/pages/ParkDetail.tsx @@ -215,19 +215,8 @@ export default function ParkDetail() { fetchParkData(); } else { // Regular users submit for moderation - const { error } = await supabase - .from('content_submissions') - .insert({ - user_id: user.id, - submission_type: 'park_edit', - status: 'pending', - content: { - park_id: park.id, - ...parkData - } - }); - - if (error) throw error; + const { submitParkUpdate } = await import('@/lib/entitySubmissionHelpers'); + await submitParkUpdate(park.id, parkData, user.id); toast({ title: "Edit Submitted", diff --git a/src/pages/Parks.tsx b/src/pages/Parks.tsx index c2dfc454..6e08b702 100644 --- a/src/pages/Parks.tsx +++ b/src/pages/Parks.tsx @@ -250,17 +250,8 @@ export default function Parks() { } try { - // All users submit for moderation - const { error } = await supabase - .from('content_submissions') - .insert({ - user_id: user.id, - submission_type: 'park', - status: 'pending', - content: parkData - }); - - if (error) throw error; + const { submitParkCreation } = await import('@/lib/entitySubmissionHelpers'); + await submitParkCreation(parkData, user.id); toast({ title: "Park Submitted",