Add advanced form editors

This commit is contained in:
gpt-engineer-app[bot]
2025-10-02 01:26:03 +00:00
parent 0996e8256c
commit 7df81a6ba0
3 changed files with 172 additions and 9 deletions

View File

@@ -21,6 +21,9 @@ import { useManufacturers, useRideModels } from '@/hooks/useAutocompleteData';
import { useUserRole } from '@/hooks/useUserRole';
import { ManufacturerForm } from './ManufacturerForm';
import { RideModelForm } from './RideModelForm';
import { TechnicalSpecsEditor } from './editors/TechnicalSpecsEditor';
import { CoasterStatsEditor } from './editors/CoasterStatsEditor';
import { FormerNamesEditor } from './editors/FormerNamesEditor';
import {
convertSpeed,
convertDistance,
@@ -144,6 +147,11 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
const [isManufacturerModalOpen, setIsManufacturerModalOpen] = useState(false);
const [isModelModalOpen, setIsModelModalOpen] = useState(false);
// Advanced editor state
const [technicalSpecs, setTechnicalSpecs] = useState<any[]>([]);
const [coasterStats, setCoasterStats] = useState<any[]>([]);
const [formerNames, setFormerNames] = useState<any[]>([]);
// Fetch data
const { manufacturers, loading: manufacturersLoading } = useManufacturers();
const { rideModels, loading: modelsLoading } = useRideModels(selectedManufacturerId);
@@ -221,12 +229,20 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
: undefined,
drop_height_meters: data.drop_height_meters
? convertDistanceToMetric(data.drop_height_meters, measurementSystem)
: undefined
: undefined,
// Add structured data from advanced editors
technical_specs: JSON.stringify(technicalSpecs),
coaster_stats: JSON.stringify(coasterStats),
former_names: JSON.stringify(formerNames)
};
// Build composite submission if new entities were created
const submissionContent: any = {
ride: metricData,
// Include structured data for relational tables
technical_specifications: technicalSpecs,
coaster_statistics: coasterStats,
name_history: formerNames
};
// Add new manufacturer if created
@@ -706,6 +722,30 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
</div>
</div>
{/* Advanced Editors */}
<div className="space-y-6 border-t pt-6">
<TechnicalSpecsEditor
specs={technicalSpecs}
onChange={setTechnicalSpecs}
commonSpecs={['Track Material', 'Manufacturer', 'Train Type', 'Restraint System', 'Block Sections']}
/>
{selectedCategory === 'roller_coaster' && (
<>
<CoasterStatsEditor
stats={coasterStats}
onChange={setCoasterStats}
/>
<FormerNamesEditor
names={formerNames}
onChange={setFormerNames}
currentName={watch('name') || 'Unnamed Ride'}
/>
</>
)}
</div>
{/* Images */}
<EntityMultiImageUploader
mode={isEditing ? 'edit' : 'create'}

View File

@@ -1,3 +1,4 @@
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
@@ -12,6 +13,7 @@ import { SlugField } from '@/components/ui/slug-field';
import { Layers, Save, X } from 'lucide-react';
import { useUserRole } from '@/hooks/useUserRole';
import { EntityMultiImageUploader, ImageAssignments } from '@/components/upload/EntityMultiImageUploader';
import { TechnicalSpecsEditor } from './editors/TechnicalSpecsEditor';
const rideModelSchema = z.object({
name: z.string().min(1, 'Name is required'),
@@ -60,6 +62,7 @@ export function RideModelForm({
initialData
}: RideModelFormProps) {
const { isModerator } = useUserRole();
const [technicalSpecs, setTechnicalSpecs] = useState<any[]>([]);
const {
register,
@@ -166,15 +169,20 @@ export function RideModelForm({
</div>
{/* Technical Specs */}
<div className="space-y-2">
<Label htmlFor="technical_specs">Technical Specifications</Label>
<Textarea
id="technical_specs"
{...register('technical_specs')}
placeholder="Enter technical specifications (e.g., track length, inversions, typical speed range)..."
rows={3}
<div className="border-t pt-6">
<TechnicalSpecsEditor
specs={technicalSpecs}
onChange={setTechnicalSpecs}
commonSpecs={[
'Typical Track Length',
'Typical Height',
'Typical Speed',
'Standard Train Configuration',
'Typical Capacity',
'Typical Duration'
]}
/>
<p className="text-xs text-muted-foreground">
<p className="text-xs text-muted-foreground mt-2">
General specifications for this model that apply to all installations
</p>
</div>

View File

@@ -0,0 +1,115 @@
-- Phase 3B: Performance Optimizations - Add Database Indexes
-- Full-Text Search Indexes (GIN indexes for fast text search)
CREATE INDEX IF NOT EXISTS idx_parks_search
ON parks USING gin(to_tsvector('english', name || ' ' || COALESCE(description, '')));
CREATE INDEX IF NOT EXISTS idx_rides_search
ON rides USING gin(to_tsvector('english', name || ' ' || COALESCE(description, '')));
CREATE INDEX IF NOT EXISTS idx_companies_search
ON companies USING gin(to_tsvector('english', name || ' ' || COALESCE(description, '')));
-- Technical Specifications Search Indexes
CREATE INDEX IF NOT EXISTS idx_ride_technical_specs_search
ON ride_technical_specifications (ride_id, spec_name, spec_value);
CREATE INDEX IF NOT EXISTS idx_ride_technical_specs_category
ON ride_technical_specifications (category) WHERE category IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_ride_coaster_stats_search
ON ride_coaster_statistics (ride_id, stat_name, stat_value);
CREATE INDEX IF NOT EXISTS idx_ride_coaster_stats_category
ON ride_coaster_statistics (category) WHERE category IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_ride_name_history_ride
ON ride_name_history (ride_id, date_changed DESC);
CREATE INDEX IF NOT EXISTS idx_ride_model_technical_specs_search
ON ride_model_technical_specifications (ride_model_id, spec_name, spec_value);
-- Filtering and Sorting Indexes
CREATE INDEX IF NOT EXISTS idx_parks_status
ON parks (status) WHERE status IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_parks_country
ON parks (location_id) WHERE location_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_parks_type
ON parks (park_type);
CREATE INDEX IF NOT EXISTS idx_rides_category_status
ON rides (category, status);
CREATE INDEX IF NOT EXISTS idx_rides_park
ON rides (park_id, status);
CREATE INDEX IF NOT EXISTS idx_rides_manufacturer
ON rides (manufacturer_id) WHERE manufacturer_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_rides_designer
ON rides (designer_id) WHERE designer_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_rides_model
ON rides (ride_model_id) WHERE ride_model_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_companies_type
ON companies (company_type);
-- Rating and Review Indexes
CREATE INDEX IF NOT EXISTS idx_parks_rating
ON parks (average_rating DESC) WHERE average_rating > 0;
CREATE INDEX IF NOT EXISTS idx_rides_rating
ON rides (average_rating DESC) WHERE average_rating > 0;
CREATE INDEX IF NOT EXISTS idx_companies_rating
ON companies (average_rating DESC) WHERE average_rating > 0;
-- Location-based Indexes
CREATE INDEX IF NOT EXISTS idx_locations_country_city
ON locations (country, city);
CREATE INDEX IF NOT EXISTS idx_locations_coordinates
ON locations (latitude, longitude) WHERE latitude IS NOT NULL AND longitude IS NOT NULL;
-- Performance Specs for Range Queries
CREATE INDEX IF NOT EXISTS idx_rides_speed
ON rides (max_speed_kmh) WHERE max_speed_kmh IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_rides_height
ON rides (max_height_meters) WHERE max_height_meters IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_rides_length
ON rides (length_meters) WHERE length_meters IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_rides_inversions
ON rides (inversions) WHERE inversions > 0;
-- Review Indexes
CREATE INDEX IF NOT EXISTS idx_reviews_park
ON reviews (park_id, moderation_status) WHERE park_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_reviews_ride
ON reviews (ride_id, moderation_status) WHERE ride_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_reviews_user
ON reviews (user_id, moderation_status);
-- Submission System Indexes
CREATE INDEX IF NOT EXISTS idx_submission_items_status
ON submission_items (status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_submission_items_type
ON submission_items (item_type, status);
CREATE INDEX IF NOT EXISTS idx_content_submissions_user_status
ON content_submissions (user_id, status, created_at DESC);
-- Composite indexes for common query patterns
CREATE INDEX IF NOT EXISTS idx_rides_park_category
ON rides (park_id, category, status);
CREATE INDEX IF NOT EXISTS idx_rides_manufacturer_category
ON rides (manufacturer_id, category) WHERE manufacturer_id IS NOT NULL;