feat: Add imperial unit support to ride form

This commit is contained in:
gpt-engineer-app[bot]
2025-09-29 20:17:03 +00:00
parent c504f25a64
commit 07b036bb7d
2 changed files with 82 additions and 17 deletions

View File

@@ -12,6 +12,18 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
import { DatePicker } from '@/components/ui/date-picker';
import { toast } from '@/hooks/use-toast';
import { Zap, Save, X } from 'lucide-react';
import { useUnitPreferences } from '@/hooks/useUnitPreferences';
import {
convertSpeed,
convertDistance,
convertHeight,
convertSpeedToMetric,
convertDistanceToMetric,
convertHeightToMetric,
getSpeedUnit,
getDistanceUnit,
getHeightUnit
} from '@/lib/units';
const rideSchema = z.object({
name: z.string().min(1, 'Ride name is required'),
@@ -96,6 +108,8 @@ const intensityLevels = [
export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }: RideFormProps) {
const [submitting, setSubmitting] = useState(false);
const [rideImage, setRideImage] = useState<string>(initialData?.image_url || '');
const { preferences } = useUnitPreferences();
const measurementSystem = preferences.measurement_system;
const {
register,
@@ -114,18 +128,29 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
status: initialData?.status || 'Operating',
opening_date: initialData?.opening_date || '',
closing_date: initialData?.closing_date || '',
height_requirement: initialData?.height_requirement || undefined,
// Convert metric values to user's preferred unit for display
height_requirement: initialData?.height_requirement
? convertHeight(initialData.height_requirement, measurementSystem)
: undefined,
age_requirement: initialData?.age_requirement || undefined,
capacity_per_hour: initialData?.capacity_per_hour || undefined,
duration_seconds: initialData?.duration_seconds || undefined,
max_speed_kmh: initialData?.max_speed_kmh || undefined,
max_height_meters: initialData?.max_height_meters || undefined,
length_meters: initialData?.length_meters || undefined,
max_speed_kmh: initialData?.max_speed_kmh
? convertSpeed(initialData.max_speed_kmh, measurementSystem)
: undefined,
max_height_meters: initialData?.max_height_meters
? convertDistance(initialData.max_height_meters, measurementSystem)
: undefined,
length_meters: initialData?.length_meters
? convertDistance(initialData.length_meters, measurementSystem)
: undefined,
inversions: initialData?.inversions || undefined,
coaster_type: initialData?.coaster_type || undefined,
seating_type: initialData?.seating_type || undefined,
intensity_level: initialData?.intensity_level || undefined,
drop_height_meters: initialData?.drop_height_meters || undefined,
drop_height_meters: initialData?.drop_height_meters
? convertDistance(initialData.drop_height_meters, measurementSystem)
: undefined,
max_g_force: initialData?.max_g_force || undefined,
former_names: initialData?.former_names || '',
coaster_stats: initialData?.coaster_stats || '',
@@ -153,10 +178,28 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
const handleFormSubmit = async (data: RideFormData) => {
setSubmitting(true);
try {
await onSubmit({
// Convert form values back to metric for storage
const metricData = {
...data,
height_requirement: data.height_requirement
? convertHeightToMetric(data.height_requirement, measurementSystem)
: undefined,
max_speed_kmh: data.max_speed_kmh
? convertSpeedToMetric(data.max_speed_kmh, measurementSystem)
: undefined,
max_height_meters: data.max_height_meters
? convertDistanceToMetric(data.max_height_meters, measurementSystem)
: undefined,
length_meters: data.length_meters
? convertDistanceToMetric(data.length_meters, measurementSystem)
: undefined,
drop_height_meters: data.drop_height_meters
? convertDistanceToMetric(data.drop_height_meters, measurementSystem)
: undefined,
image_url: rideImage || undefined
});
};
await onSubmit(metricData);
toast({
title: isEditing ? "Ride Updated" : "Ride Created",
@@ -305,13 +348,13 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
{/* Requirements */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<Label htmlFor="height_requirement">Height Requirement (cm)</Label>
<Label htmlFor="height_requirement">Height Requirement ({getHeightUnit(measurementSystem)})</Label>
<Input
id="height_requirement"
type="number"
min="0"
{...register('height_requirement', { valueAsNumber: true })}
placeholder="e.g. 120"
placeholder={measurementSystem === 'imperial' ? 'e.g. 47' : 'e.g. 120'}
/>
</div>
@@ -384,14 +427,14 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<Label htmlFor="drop_height_meters">Drop Height (meters)</Label>
<Label htmlFor="drop_height_meters">Drop Height ({getDistanceUnit(measurementSystem)})</Label>
<Input
id="drop_height_meters"
type="number"
min="0"
step="0.1"
{...register('drop_height_meters', { valueAsNumber: true })}
placeholder="e.g. 45.5"
placeholder={measurementSystem === 'imperial' ? 'e.g. 149' : 'e.g. 45.5'}
/>
</div>
@@ -438,38 +481,38 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
</div>
<div className="space-y-2">
<Label htmlFor="max_speed_kmh">Max Speed (km/h)</Label>
<Label htmlFor="max_speed_kmh">Max Speed ({getSpeedUnit(measurementSystem)})</Label>
<Input
id="max_speed_kmh"
type="number"
min="0"
step="0.1"
{...register('max_speed_kmh', { valueAsNumber: true })}
placeholder="e.g. 80.5"
placeholder={measurementSystem === 'imperial' ? 'e.g. 50' : 'e.g. 80.5'}
/>
</div>
<div className="space-y-2">
<Label htmlFor="max_height_meters">Max Height (meters)</Label>
<Label htmlFor="max_height_meters">Max Height ({getDistanceUnit(measurementSystem)})</Label>
<Input
id="max_height_meters"
type="number"
min="0"
step="0.1"
{...register('max_height_meters', { valueAsNumber: true })}
placeholder="e.g. 65.2"
placeholder={measurementSystem === 'imperial' ? 'e.g. 214' : 'e.g. 65.2'}
/>
</div>
<div className="space-y-2">
<Label htmlFor="length_meters">Length (meters)</Label>
<Label htmlFor="length_meters">Length ({getDistanceUnit(measurementSystem)})</Label>
<Input
id="length_meters"
type="number"
min="0"
step="0.1"
{...register('length_meters', { valueAsNumber: true })}
placeholder="e.g. 1200.5"
placeholder={measurementSystem === 'imperial' ? 'e.g. 3937' : 'e.g. 1200.5'}
/>
</div>