diff --git a/src/components/moderation/displays/RichRideDisplay.tsx b/src/components/moderation/displays/RichRideDisplay.tsx index 81886189..4e0b3f90 100644 --- a/src/components/moderation/displays/RichRideDisplay.tsx +++ b/src/components/moderation/displays/RichRideDisplay.tsx @@ -63,7 +63,8 @@ export function RichRideDisplay({ data, actionType, showAllFields = true }: Rich fetchRelatedData(); }, [data.park_id, data.manufacturer_id, data.designer_id, data.ride_model_id]); - const getStatusColor = (status: string) => { + const getStatusColor = (status: string | undefined) => { + if (!status) return 'bg-gray-500'; switch (status.toLowerCase()) { case 'operating': return 'bg-green-500'; case 'closed': return 'bg-red-500'; diff --git a/supabase/migrations/20251104224912_353fa7db-ae50-4c1d-a468-bcd81fc260dc.sql b/supabase/migrations/20251104224912_353fa7db-ae50-4c1d-a468-bcd81fc260dc.sql new file mode 100644 index 00000000..3e4a2b67 --- /dev/null +++ b/supabase/migrations/20251104224912_353fa7db-ae50-4c1d-a468-bcd81fc260dc.sql @@ -0,0 +1,184 @@ +-- Fix create_submission_with_items to properly handle composite submissions +-- Creates specialized records (park_submissions, company_submissions, etc.) and links them + +CREATE OR REPLACE FUNCTION public.create_submission_with_items( + p_user_id uuid, + p_submission_type text, + p_content jsonb, -- Keep for backward compatibility + p_items jsonb[] +) +RETURNS uuid +LANGUAGE plpgsql +SECURITY DEFINER +SET search_path TO 'public' +AS $$ +DECLARE + v_submission_id UUID; + v_item JSONB; + v_item_data JSONB; + v_item_type TEXT; + v_action_type TEXT; + v_park_submission_id UUID; + v_company_submission_id UUID; + v_ride_submission_id UUID; + v_ride_model_submission_id UUID; + v_photo_submission_id UUID; +BEGIN + -- Create main submission + INSERT INTO content_submissions (user_id, submission_type, status, approval_mode) + VALUES (p_user_id, p_submission_type, 'pending', 'full') + RETURNING id INTO v_submission_id; + + -- Validate items array + IF array_length(p_items, 1) IS NULL OR array_length(p_items, 1) = 0 THEN + RAISE EXCEPTION 'Cannot create submission without items'; + END IF; + + -- Process each item + FOREACH v_item IN ARRAY p_items + LOOP + v_item_type := (v_item->>'item_type')::TEXT; + v_action_type := (v_item->>'action_type')::TEXT; + v_item_data := v_item->'item_data'; + + -- Reset IDs for this iteration + v_park_submission_id := (v_item->>'park_submission_id')::UUID; + v_company_submission_id := (v_item->>'company_submission_id')::UUID; + v_ride_submission_id := (v_item->>'ride_submission_id')::UUID; + v_ride_model_submission_id := (v_item->>'ride_model_submission_id')::UUID; + v_photo_submission_id := (v_item->>'photo_submission_id')::UUID; + + -- Create specialized submission if item_data exists (for new entities) + IF v_item_data IS NOT NULL AND jsonb_typeof(v_item_data) = 'object' THEN + + IF v_item_type = 'park' THEN + INSERT INTO park_submissions ( + submission_id, name, slug, description, park_type, status, + opening_date, closing_date, opening_date_precision, closing_date_precision, + website_url, phone, email, location_id, + operator_id, property_owner_id, + banner_image_url, banner_image_id, card_image_url, card_image_id + ) VALUES ( + v_submission_id, + v_item_data->>'name', + v_item_data->>'slug', + v_item_data->>'description', + v_item_data->>'park_type', + v_item_data->>'status', + (v_item_data->>'opening_date')::DATE, + (v_item_data->>'closing_date')::DATE, + v_item_data->>'opening_date_precision', + v_item_data->>'closing_date_precision', + v_item_data->>'website_url', + v_item_data->>'phone', + v_item_data->>'email', + (v_item_data->>'location_id')::UUID, + (v_item_data->>'operator_id')::UUID, + (v_item_data->>'property_owner_id')::UUID, + v_item_data->>'banner_image_url', + v_item_data->>'banner_image_id', + v_item_data->>'card_image_url', + v_item_data->>'card_image_id' + ) RETURNING id INTO v_park_submission_id; + + ELSIF v_item_type IN ('operator', 'property_owner', 'manufacturer', 'designer') THEN + INSERT INTO company_submissions ( + submission_id, name, slug, description, company_type, person_type, + founded_year, founded_date, founded_date_precision, + headquarters_location, website_url, + logo_url, banner_image_url, banner_image_id, + card_image_url, card_image_id + ) VALUES ( + v_submission_id, + v_item_data->>'name', + v_item_data->>'slug', + v_item_data->>'description', + v_item_data->>'company_type', + v_item_data->>'person_type', + (v_item_data->>'founded_year')::INTEGER, + (v_item_data->>'founded_date')::DATE, + v_item_data->>'founded_date_precision', + v_item_data->>'headquarters_location', + v_item_data->>'website_url', + v_item_data->>'logo_url', + v_item_data->>'banner_image_url', + v_item_data->>'banner_image_id', + v_item_data->>'card_image_url', + v_item_data->>'card_image_id' + ) RETURNING id INTO v_company_submission_id; + + ELSIF v_item_type = 'ride' THEN + INSERT INTO ride_submissions ( + submission_id, name, slug, description, category, status, + park_id, manufacturer_id, designer_id, ride_model_id, + opening_date, closing_date, opening_date_precision, closing_date_precision, + height_requirement_cm, age_requirement, + max_speed_kmh, duration_seconds, capacity_per_hour, + gforce_max, inversions_count, + length_meters, height_meters, drop_meters, + banner_image_url, banner_image_id, card_image_url, card_image_id + ) VALUES ( + v_submission_id, + v_item_data->>'name', + v_item_data->>'slug', + v_item_data->>'description', + v_item_data->>'category', + v_item_data->>'status', + (v_item_data->>'park_id')::UUID, + (v_item_data->>'manufacturer_id')::UUID, + (v_item_data->>'designer_id')::UUID, + (v_item_data->>'ride_model_id')::UUID, + (v_item_data->>'opening_date')::DATE, + (v_item_data->>'closing_date')::DATE, + v_item_data->>'opening_date_precision', + v_item_data->>'closing_date_precision', + (v_item_data->>'height_requirement_cm')::INTEGER, + (v_item_data->>'age_requirement')::INTEGER, + (v_item_data->>'max_speed_kmh')::NUMERIC, + (v_item_data->>'duration_seconds')::INTEGER, + (v_item_data->>'capacity_per_hour')::INTEGER, + (v_item_data->>'gforce_max')::NUMERIC, + (v_item_data->>'inversions_count')::INTEGER, + (v_item_data->>'length_meters')::NUMERIC, + (v_item_data->>'height_meters')::NUMERIC, + (v_item_data->>'drop_meters')::NUMERIC, + v_item_data->>'banner_image_url', + v_item_data->>'banner_image_id', + v_item_data->>'card_image_url', + v_item_data->>'card_image_id' + ) RETURNING id INTO v_ride_submission_id; + + END IF; + END IF; + + -- Insert submission_item with proper foreign key linkage + INSERT INTO submission_items ( + submission_id, + item_type, + action_type, + park_submission_id, + company_submission_id, + ride_submission_id, + ride_model_submission_id, + photo_submission_id, + status, + order_index, + depends_on + ) VALUES ( + v_submission_id, + v_item_type, + v_action_type, + v_park_submission_id, + v_company_submission_id, + v_ride_submission_id, + v_ride_model_submission_id, + v_photo_submission_id, + 'pending', + COALESCE((v_item->>'order_index')::INTEGER, 0), + (v_item->>'depends_on')::UUID + ); + END LOOP; + + RETURN v_submission_id; +END; +$$; \ No newline at end of file