mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 17:31:15 -05:00
feat: Add imperial unit support to ride form
This commit is contained in:
@@ -12,6 +12,18 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
|
|||||||
import { DatePicker } from '@/components/ui/date-picker';
|
import { DatePicker } from '@/components/ui/date-picker';
|
||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { Zap, Save, X } from 'lucide-react';
|
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({
|
const rideSchema = z.object({
|
||||||
name: z.string().min(1, 'Ride name is required'),
|
name: z.string().min(1, 'Ride name is required'),
|
||||||
@@ -96,6 +108,8 @@ const intensityLevels = [
|
|||||||
export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }: RideFormProps) {
|
export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }: RideFormProps) {
|
||||||
const [submitting, setSubmitting] = useState(false);
|
const [submitting, setSubmitting] = useState(false);
|
||||||
const [rideImage, setRideImage] = useState<string>(initialData?.image_url || '');
|
const [rideImage, setRideImage] = useState<string>(initialData?.image_url || '');
|
||||||
|
const { preferences } = useUnitPreferences();
|
||||||
|
const measurementSystem = preferences.measurement_system;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
@@ -114,18 +128,29 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
|||||||
status: initialData?.status || 'Operating',
|
status: initialData?.status || 'Operating',
|
||||||
opening_date: initialData?.opening_date || '',
|
opening_date: initialData?.opening_date || '',
|
||||||
closing_date: initialData?.closing_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,
|
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 || undefined,
|
max_speed_kmh: initialData?.max_speed_kmh
|
||||||
max_height_meters: initialData?.max_height_meters || undefined,
|
? convertSpeed(initialData.max_speed_kmh, measurementSystem)
|
||||||
length_meters: initialData?.length_meters || undefined,
|
: 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,
|
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 || undefined,
|
drop_height_meters: initialData?.drop_height_meters
|
||||||
|
? convertDistance(initialData.drop_height_meters, measurementSystem)
|
||||||
|
: 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 || '',
|
||||||
coaster_stats: initialData?.coaster_stats || '',
|
coaster_stats: initialData?.coaster_stats || '',
|
||||||
@@ -153,10 +178,28 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
|||||||
const handleFormSubmit = async (data: RideFormData) => {
|
const handleFormSubmit = async (data: RideFormData) => {
|
||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
try {
|
try {
|
||||||
await onSubmit({
|
// Convert form values back to metric for storage
|
||||||
|
const metricData = {
|
||||||
...data,
|
...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
|
image_url: rideImage || undefined
|
||||||
});
|
};
|
||||||
|
|
||||||
|
await onSubmit(metricData);
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: isEditing ? "Ride Updated" : "Ride Created",
|
title: isEditing ? "Ride Updated" : "Ride Created",
|
||||||
@@ -305,13 +348,13 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
|||||||
{/* Requirements */}
|
{/* Requirements */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="height_requirement">Height Requirement (cm)</Label>
|
<Label htmlFor="height_requirement">Height Requirement ({getHeightUnit(measurementSystem)})</Label>
|
||||||
<Input
|
<Input
|
||||||
id="height_requirement"
|
id="height_requirement"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
{...register('height_requirement', { valueAsNumber: true })}
|
{...register('height_requirement', { valueAsNumber: true })}
|
||||||
placeholder="e.g. 120"
|
placeholder={measurementSystem === 'imperial' ? 'e.g. 47' : 'e.g. 120'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</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="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<div className="space-y-2">
|
<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
|
<Input
|
||||||
id="drop_height_meters"
|
id="drop_height_meters"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
step="0.1"
|
step="0.1"
|
||||||
{...register('drop_height_meters', { valueAsNumber: true })}
|
{...register('drop_height_meters', { valueAsNumber: true })}
|
||||||
placeholder="e.g. 45.5"
|
placeholder={measurementSystem === 'imperial' ? 'e.g. 149' : 'e.g. 45.5'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -438,38 +481,38 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<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
|
<Input
|
||||||
id="max_speed_kmh"
|
id="max_speed_kmh"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
step="0.1"
|
step="0.1"
|
||||||
{...register('max_speed_kmh', { valueAsNumber: true })}
|
{...register('max_speed_kmh', { valueAsNumber: true })}
|
||||||
placeholder="e.g. 80.5"
|
placeholder={measurementSystem === 'imperial' ? 'e.g. 50' : 'e.g. 80.5'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<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
|
<Input
|
||||||
id="max_height_meters"
|
id="max_height_meters"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
step="0.1"
|
step="0.1"
|
||||||
{...register('max_height_meters', { valueAsNumber: true })}
|
{...register('max_height_meters', { valueAsNumber: true })}
|
||||||
placeholder="e.g. 65.2"
|
placeholder={measurementSystem === 'imperial' ? 'e.g. 214' : 'e.g. 65.2'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="length_meters">Length (meters)</Label>
|
<Label htmlFor="length_meters">Length ({getDistanceUnit(measurementSystem)})</Label>
|
||||||
<Input
|
<Input
|
||||||
id="length_meters"
|
id="length_meters"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
step="0.1"
|
step="0.1"
|
||||||
{...register('length_meters', { valueAsNumber: true })}
|
{...register('length_meters', { valueAsNumber: true })}
|
||||||
placeholder="e.g. 1200.5"
|
placeholder={measurementSystem === 'imperial' ? 'e.g. 3937' : 'e.g. 1200.5'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,28 @@ export function convertHeight(cm: number, system: MeasurementSystem): number {
|
|||||||
return Math.round(cm);
|
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
|
// 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';
|
||||||
|
|||||||
Reference in New Issue
Block a user