mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 13:31:22 -05:00
Refactor: Implement cleanup plan
This commit is contained in:
@@ -25,12 +25,9 @@ import { TechnicalSpecsEditor } from './editors/TechnicalSpecsEditor';
|
|||||||
import { CoasterStatsEditor } from './editors/CoasterStatsEditor';
|
import { CoasterStatsEditor } from './editors/CoasterStatsEditor';
|
||||||
import { FormerNamesEditor } from './editors/FormerNamesEditor';
|
import { FormerNamesEditor } from './editors/FormerNamesEditor';
|
||||||
import {
|
import {
|
||||||
convertSpeed,
|
convertValueToMetric,
|
||||||
convertDistance,
|
convertValueFromMetric,
|
||||||
convertHeight,
|
getDisplayUnit,
|
||||||
convertSpeedToMetric,
|
|
||||||
convertDistanceToMetric,
|
|
||||||
convertHeightToMetric,
|
|
||||||
getSpeedUnit,
|
getSpeedUnit,
|
||||||
getDistanceUnit,
|
getDistanceUnit,
|
||||||
getHeightUnit
|
getHeightUnit
|
||||||
@@ -202,26 +199,26 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
|||||||
closing_date: initialData?.closing_date || '',
|
closing_date: initialData?.closing_date || '',
|
||||||
// Convert metric values to user's preferred unit for display
|
// Convert metric values to user's preferred unit for display
|
||||||
height_requirement: initialData?.height_requirement
|
height_requirement: initialData?.height_requirement
|
||||||
? convertHeight(initialData.height_requirement, measurementSystem)
|
? convertValueFromMetric(initialData.height_requirement, getDisplayUnit('cm', measurementSystem), 'cm')
|
||||||
: undefined,
|
: undefined,
|
||||||
age_requirement: initialData?.age_requirement || undefined,
|
age_requirement: initialData?.age_requirement || undefined,
|
||||||
capacity_per_hour: initialData?.capacity_per_hour || undefined,
|
capacity_per_hour: initialData?.capacity_per_hour || undefined,
|
||||||
duration_seconds: initialData?.duration_seconds || undefined,
|
duration_seconds: initialData?.duration_seconds || undefined,
|
||||||
max_speed_kmh: initialData?.max_speed_kmh
|
max_speed_kmh: initialData?.max_speed_kmh
|
||||||
? convertSpeed(initialData.max_speed_kmh, measurementSystem)
|
? convertValueFromMetric(initialData.max_speed_kmh, getDisplayUnit('km/h', measurementSystem), 'km/h')
|
||||||
: undefined,
|
: undefined,
|
||||||
max_height_meters: initialData?.max_height_meters
|
max_height_meters: initialData?.max_height_meters
|
||||||
? convertDistance(initialData.max_height_meters, measurementSystem)
|
? convertValueFromMetric(initialData.max_height_meters, getDisplayUnit('m', measurementSystem), 'm')
|
||||||
: undefined,
|
: undefined,
|
||||||
length_meters: initialData?.length_meters
|
length_meters: initialData?.length_meters
|
||||||
? convertDistance(initialData.length_meters, measurementSystem)
|
? convertValueFromMetric(initialData.length_meters, getDisplayUnit('m', measurementSystem), 'm')
|
||||||
: undefined,
|
: undefined,
|
||||||
inversions: initialData?.inversions || undefined,
|
inversions: initialData?.inversions || undefined,
|
||||||
coaster_type: initialData?.coaster_type || undefined,
|
coaster_type: initialData?.coaster_type || undefined,
|
||||||
seating_type: initialData?.seating_type || undefined,
|
seating_type: initialData?.seating_type || undefined,
|
||||||
intensity_level: initialData?.intensity_level || undefined,
|
intensity_level: initialData?.intensity_level || undefined,
|
||||||
drop_height_meters: initialData?.drop_height_meters
|
drop_height_meters: initialData?.drop_height_meters
|
||||||
? convertDistance(initialData.drop_height_meters, measurementSystem)
|
? convertValueFromMetric(initialData.drop_height_meters, getDisplayUnit('m', measurementSystem), 'm')
|
||||||
: undefined,
|
: undefined,
|
||||||
max_g_force: initialData?.max_g_force || undefined,
|
max_g_force: initialData?.max_g_force || undefined,
|
||||||
former_names: initialData?.former_names || '',
|
former_names: initialData?.former_names || '',
|
||||||
@@ -247,19 +244,19 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
|||||||
...data,
|
...data,
|
||||||
status: dbStatus,
|
status: dbStatus,
|
||||||
height_requirement: data.height_requirement
|
height_requirement: data.height_requirement
|
||||||
? convertHeightToMetric(data.height_requirement, measurementSystem)
|
? convertValueToMetric(data.height_requirement, getDisplayUnit('cm', measurementSystem))
|
||||||
: undefined,
|
: undefined,
|
||||||
max_speed_kmh: data.max_speed_kmh
|
max_speed_kmh: data.max_speed_kmh
|
||||||
? convertSpeedToMetric(data.max_speed_kmh, measurementSystem)
|
? convertValueToMetric(data.max_speed_kmh, getDisplayUnit('km/h', measurementSystem))
|
||||||
: undefined,
|
: undefined,
|
||||||
max_height_meters: data.max_height_meters
|
max_height_meters: data.max_height_meters
|
||||||
? convertDistanceToMetric(data.max_height_meters, measurementSystem)
|
? convertValueToMetric(data.max_height_meters, getDisplayUnit('m', measurementSystem))
|
||||||
: undefined,
|
: undefined,
|
||||||
length_meters: data.length_meters
|
length_meters: data.length_meters
|
||||||
? convertDistanceToMetric(data.length_meters, measurementSystem)
|
? convertValueToMetric(data.length_meters, getDisplayUnit('m', measurementSystem))
|
||||||
: undefined,
|
: undefined,
|
||||||
drop_height_meters: data.drop_height_meters
|
drop_height_meters: data.drop_height_meters
|
||||||
? convertDistanceToMetric(data.drop_height_meters, measurementSystem)
|
? convertValueToMetric(data.drop_height_meters, getDisplayUnit('m', measurementSystem))
|
||||||
: undefined,
|
: undefined,
|
||||||
// ⚠️ Remove JSON stringification - use relational tables instead
|
// ⚠️ Remove JSON stringification - use relational tables instead
|
||||||
// These fields are deprecated and should not be set
|
// These fields are deprecated and should not be set
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
/**
|
|
||||||
* @deprecated Use EntityPhotoGallery directly or import from RidePhotoGalleryWrapper
|
|
||||||
* This file is kept for backwards compatibility
|
|
||||||
*/
|
|
||||||
export { RidePhotoGallery } from './RidePhotoGalleryWrapper';
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
|
|
||||||
|
|
||||||
interface RidePhotoGalleryProps {
|
|
||||||
rideId: string;
|
|
||||||
rideName: string;
|
|
||||||
parkId?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Backwards-compatible wrapper for RidePhotoGallery
|
|
||||||
* Uses the generic EntityPhotoGallery component internally
|
|
||||||
*/
|
|
||||||
export function RidePhotoGallery({ rideId, rideName, parkId }: RidePhotoGalleryProps) {
|
|
||||||
return (
|
|
||||||
<EntityPhotoGallery
|
|
||||||
entityId={rideId}
|
|
||||||
entityType="ride"
|
|
||||||
entityName={rideName}
|
|
||||||
parentId={parkId}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useUnitPreferences } from '@/hooks/useUnitPreferences';
|
import { useUnitPreferences } from '@/hooks/useUnitPreferences';
|
||||||
import {
|
import {
|
||||||
convertSpeed,
|
convertValueFromMetric,
|
||||||
convertDistance,
|
getDisplayUnit,
|
||||||
convertHeight,
|
|
||||||
getSpeedUnit,
|
getSpeedUnit,
|
||||||
getDistanceUnit,
|
getDistanceUnit,
|
||||||
getHeightUnit,
|
getHeightUnit,
|
||||||
@@ -29,47 +28,36 @@ export function MeasurementDisplay({
|
|||||||
const { displayValue, unit, alternateDisplay, tooltipText } = useMemo(() => {
|
const { displayValue, unit, alternateDisplay, tooltipText } = useMemo(() => {
|
||||||
const system = unitPreferences.measurement_system;
|
const system = unitPreferences.measurement_system;
|
||||||
|
|
||||||
let displayValue: number;
|
let metricUnit: string;
|
||||||
let unit: string;
|
let displayUnit: string;
|
||||||
let alternateValue: number;
|
let alternateSystem: MeasurementSystem;
|
||||||
let alternateUnit: string;
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'speed':
|
case 'speed':
|
||||||
displayValue = convertSpeed(value, system);
|
metricUnit = 'km/h';
|
||||||
unit = getSpeedUnit(system);
|
|
||||||
alternateValue = convertSpeed(value, system === 'metric' ? 'imperial' : 'metric');
|
|
||||||
alternateUnit = getSpeedUnit(system === 'metric' ? 'imperial' : 'metric');
|
|
||||||
break;
|
break;
|
||||||
case 'distance':
|
case 'distance':
|
||||||
displayValue = convertDistance(value, system);
|
case 'short_distance':
|
||||||
unit = getDistanceUnit(system);
|
metricUnit = 'm';
|
||||||
alternateValue = convertDistance(value, system === 'metric' ? 'imperial' : 'metric');
|
|
||||||
alternateUnit = getDistanceUnit(system === 'metric' ? 'imperial' : 'metric');
|
|
||||||
break;
|
break;
|
||||||
case 'height':
|
case 'height':
|
||||||
displayValue = convertHeight(value, system);
|
metricUnit = 'cm';
|
||||||
unit = getHeightUnit(system);
|
|
||||||
alternateValue = convertHeight(value, system === 'metric' ? 'imperial' : 'metric');
|
|
||||||
alternateUnit = getHeightUnit(system === 'metric' ? 'imperial' : 'metric');
|
|
||||||
break;
|
|
||||||
case 'short_distance':
|
|
||||||
displayValue = convertDistance(value, system);
|
|
||||||
unit = getShortDistanceUnit(system);
|
|
||||||
alternateValue = convertDistance(value, system === 'metric' ? 'imperial' : 'metric');
|
|
||||||
alternateUnit = getShortDistanceUnit(system === 'metric' ? 'imperial' : 'metric');
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
displayValue = value;
|
return { displayValue: value, unit: '', alternateDisplay: '', tooltipText: undefined };
|
||||||
unit = '';
|
|
||||||
alternateValue = value;
|
|
||||||
alternateUnit = '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alternateSystem = system === 'metric' ? 'imperial' : 'metric';
|
||||||
|
displayUnit = getDisplayUnit(metricUnit, system);
|
||||||
|
const alternateUnit = getDisplayUnit(metricUnit, alternateSystem);
|
||||||
|
|
||||||
|
const displayValue = convertValueFromMetric(value, displayUnit, metricUnit);
|
||||||
|
const alternateValue = convertValueFromMetric(value, alternateUnit, metricUnit);
|
||||||
|
|
||||||
const alternateDisplay = showBothUnits ? ` (${alternateValue} ${alternateUnit})` : '';
|
const alternateDisplay = showBothUnits ? ` (${alternateValue} ${alternateUnit})` : '';
|
||||||
const tooltipText = showBothUnits ? undefined : `${alternateValue} ${alternateUnit}`;
|
const tooltipText = showBothUnits ? undefined : `${alternateValue} ${alternateUnit}`;
|
||||||
|
|
||||||
return { displayValue, unit, alternateDisplay, tooltipText };
|
return { displayValue, unit: displayUnit, alternateDisplay, tooltipText };
|
||||||
}, [value, type, unitPreferences.measurement_system, showBothUnits]);
|
}, [value, type, unitPreferences.measurement_system, showBothUnits]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -20,14 +20,7 @@ export function UppyPhotoSubmissionUpload({
|
|||||||
entityId,
|
entityId,
|
||||||
entityType,
|
entityType,
|
||||||
parentId,
|
parentId,
|
||||||
// Legacy props (deprecated)
|
|
||||||
parkId,
|
|
||||||
rideId,
|
|
||||||
}: UppyPhotoSubmissionUploadProps) {
|
}: UppyPhotoSubmissionUploadProps) {
|
||||||
// Support legacy props
|
|
||||||
const finalEntityId = entityId || rideId || parkId || '';
|
|
||||||
const finalEntityType = entityType || (rideId ? 'ride' : parkId ? 'park' : 'ride');
|
|
||||||
const finalParentId = parentId || (rideId ? parkId : undefined);
|
|
||||||
const [title, setTitle] = useState('');
|
const [title, setTitle] = useState('');
|
||||||
const [photos, setPhotos] = useState<PhotoWithCaption[]>([]);
|
const [photos, setPhotos] = useState<PhotoWithCaption[]>([]);
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
@@ -203,9 +196,9 @@ export function UppyPhotoSubmissionUpload({
|
|||||||
.from('photo_submissions')
|
.from('photo_submissions')
|
||||||
.insert({
|
.insert({
|
||||||
submission_id: submissionData.id,
|
submission_id: submissionData.id,
|
||||||
entity_type: finalEntityType,
|
entity_type: entityType,
|
||||||
entity_id: finalEntityId,
|
entity_id: entityId,
|
||||||
parent_id: finalParentId || null,
|
parent_id: parentId || null,
|
||||||
title: title.trim() || null,
|
title: title.trim() || null,
|
||||||
})
|
})
|
||||||
.select()
|
.select()
|
||||||
@@ -239,8 +232,8 @@ export function UppyPhotoSubmissionUpload({
|
|||||||
console.log('✅ Photo submission created:', {
|
console.log('✅ Photo submission created:', {
|
||||||
submission_id: submissionData.id,
|
submission_id: submissionData.id,
|
||||||
photo_submission_id: photoSubmissionData.id,
|
photo_submission_id: photoSubmissionData.id,
|
||||||
entity_type: finalEntityType,
|
entity_type: entityType,
|
||||||
entity_id: finalEntityId,
|
entity_id: entityId,
|
||||||
photo_count: photoItems.length,
|
photo_count: photoItems.length,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -285,12 +278,9 @@ export function UppyPhotoSubmissionUpload({
|
|||||||
|
|
||||||
const metadata = {
|
const metadata = {
|
||||||
submissionType: 'photo',
|
submissionType: 'photo',
|
||||||
entityId: finalEntityId,
|
entityId,
|
||||||
entityType: finalEntityType,
|
entityType,
|
||||||
parentId: finalParentId,
|
parentId,
|
||||||
// Legacy support
|
|
||||||
parkId: finalEntityType === 'park' ? finalEntityId : finalParentId,
|
|
||||||
rideId: finalEntityType === 'ride' ? finalEntityId : undefined,
|
|
||||||
userId: user?.id,
|
userId: user?.id,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,53 +6,7 @@ export interface UnitPreferences {
|
|||||||
auto_detect: boolean;
|
auto_detect: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Speed conversions
|
// Get unit labels (helper functions - use getDisplayUnit for conversion logic)
|
||||||
export function convertSpeed(kmh: number, system: MeasurementSystem): number {
|
|
||||||
if (system === 'imperial') {
|
|
||||||
return Math.round(kmh * 0.621371);
|
|
||||||
}
|
|
||||||
return Math.round(kmh);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Distance conversions (meters to feet)
|
|
||||||
export function convertDistance(meters: number, system: MeasurementSystem): number {
|
|
||||||
if (system === 'imperial') {
|
|
||||||
return Math.round(meters * 3.28084);
|
|
||||||
}
|
|
||||||
return Math.round(meters);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Height conversions (cm to inches)
|
|
||||||
export function convertHeight(cm: number, system: MeasurementSystem): number {
|
|
||||||
if (system === 'imperial') {
|
|
||||||
return Math.round(cm * 0.393701);
|
|
||||||
}
|
|
||||||
return Math.round(cm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverse conversions (for form inputs - imperial to metric)
|
|
||||||
export function convertSpeedToMetric(value: number, system: MeasurementSystem): number {
|
|
||||||
if (system === 'imperial') {
|
|
||||||
return Math.round(value / 0.621371);
|
|
||||||
}
|
|
||||||
return Math.round(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function convertDistanceToMetric(value: number, system: MeasurementSystem): number {
|
|
||||||
if (system === 'imperial') {
|
|
||||||
return Math.round(value / 3.28084);
|
|
||||||
}
|
|
||||||
return Math.round(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function convertHeightToMetric(value: number, system: MeasurementSystem): number {
|
|
||||||
if (system === 'imperial') {
|
|
||||||
return Math.round(value / 0.393701);
|
|
||||||
}
|
|
||||||
return Math.round(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get unit labels
|
|
||||||
export function getSpeedUnit(system: MeasurementSystem): string {
|
export function getSpeedUnit(system: MeasurementSystem): string {
|
||||||
return system === 'imperial' ? 'mph' : 'km/h';
|
return system === 'imperial' ? 'mph' : 'km/h';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import {
|
|||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { ReviewsSection } from '@/components/reviews/ReviewsSection';
|
import { ReviewsSection } from '@/components/reviews/ReviewsSection';
|
||||||
import { MeasurementDisplay } from '@/components/ui/measurement-display';
|
import { MeasurementDisplay } from '@/components/ui/measurement-display';
|
||||||
import { RidePhotoGallery } from '@/components/rides/RidePhotoGallery';
|
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
|
||||||
import { RatingDistribution } from '@/components/rides/RatingDistribution';
|
import { RatingDistribution } from '@/components/rides/RatingDistribution';
|
||||||
import { RideHighlights } from '@/components/rides/RideHighlights';
|
import { RideHighlights } from '@/components/rides/RideHighlights';
|
||||||
import { SimilarRides } from '@/components/rides/SimilarRides';
|
import { SimilarRides } from '@/components/rides/SimilarRides';
|
||||||
@@ -395,8 +395,8 @@ export default function RideDetail() {
|
|||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{ride.former_names && ride.former_names.length > 0 && (
|
{ride.name_history && ride.name_history.length > 0 && (
|
||||||
<FormerNames formerNames={ride.former_names} currentName={ride.name} />
|
<FormerNames nameHistory={ride.name_history} currentName={ride.name} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<SimilarRides
|
<SimilarRides
|
||||||
@@ -638,10 +638,11 @@ export default function RideDetail() {
|
|||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="photos" className="mt-6">
|
<TabsContent value="photos" className="mt-6">
|
||||||
<RidePhotoGallery
|
<EntityPhotoGallery
|
||||||
rideId={ride.id}
|
entityId={ride.id}
|
||||||
rideName={ride.name}
|
entityType="ride"
|
||||||
parkId={(ride as any).currentParkId}
|
entityName={ride.name}
|
||||||
|
parentId={(ride as any).currentParkId}
|
||||||
/>
|
/>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
@@ -112,8 +112,7 @@ export interface RideModel {
|
|||||||
category: 'roller_coaster' | 'flat_ride' | 'water_ride' | 'dark_ride' | 'kiddie_ride' | 'transportation';
|
category: 'roller_coaster' | 'flat_ride' | 'water_ride' | 'dark_ride' | 'kiddie_ride' | 'transportation';
|
||||||
ride_type: string;
|
ride_type: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
technical_specs?: any; // ⚠️ DEPRECATED - Use ride_model_technical_specifications table instead
|
technical_specifications?: RideModelTechnicalSpec[];
|
||||||
technical_specifications?: RideModelTechnicalSpec[]; // New relational data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Ride {
|
export interface Ride {
|
||||||
@@ -138,10 +137,6 @@ export interface Ride {
|
|||||||
max_height_meters?: number;
|
max_height_meters?: number;
|
||||||
length_meters?: number;
|
length_meters?: number;
|
||||||
inversions?: number;
|
inversions?: number;
|
||||||
coaster_stats?: any; // ⚠️ DEPRECATED - Use ride_coaster_statistics table instead
|
|
||||||
technical_specs?: any; // ⚠️ DEPRECATED - Use ride_technical_specifications table instead
|
|
||||||
former_names?: any; // ⚠️ DEPRECATED - Use ride_name_history table instead
|
|
||||||
// New relational data
|
|
||||||
technical_specifications?: RideTechnicalSpec[];
|
technical_specifications?: RideTechnicalSpec[];
|
||||||
coaster_statistics?: RideCoasterStat[];
|
coaster_statistics?: RideCoasterStat[];
|
||||||
name_history?: RideNameHistory[];
|
name_history?: RideNameHistory[];
|
||||||
|
|||||||
@@ -54,10 +54,6 @@ export interface UppyPhotoSubmissionUploadProps {
|
|||||||
entityId: string;
|
entityId: string;
|
||||||
entityType: EntityType;
|
entityType: EntityType;
|
||||||
parentId?: string; // Optional parent (e.g., parkId for rides)
|
parentId?: string; // Optional parent (e.g., parkId for rides)
|
||||||
|
|
||||||
// Deprecated (kept for backwards compatibility)
|
|
||||||
parkId?: string;
|
|
||||||
rideId?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user