Refactor profile stats calculation

This commit is contained in:
gpt-engineer-app[bot]
2025-09-28 21:15:23 +00:00
parent 2f295b4879
commit ec664a1669
5 changed files with 250 additions and 2 deletions

View File

@@ -28,7 +28,16 @@ const rideSchema = z.object({
max_speed_kmh: z.number().optional(),
max_height_meters: z.number().optional(),
length_meters: z.number().optional(),
inversions: z.number().optional()
inversions: z.number().optional(),
// New roller coaster specific fields
coaster_type: z.string().optional(),
seating_type: z.string().optional(),
intensity_level: z.string().optional(),
drop_height_meters: z.number().optional(),
max_g_force: z.number().optional(),
former_names: z.string().optional(),
coaster_stats: z.string().optional(),
technical_specs: z.string().optional()
});
type RideFormData = z.infer<typeof rideSchema>;
@@ -59,6 +68,30 @@ const statusOptions = [
'SBNO' // Standing But Not Operating
];
const coasterTypes = [
'steel',
'wood',
'hybrid'
];
const seatingTypes = [
'sit_down',
'stand_up',
'flying',
'inverted',
'floorless',
'suspended',
'wing',
'dive',
'spinning'
];
const intensityLevels = [
'family',
'thrill',
'extreme'
];
export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }: RideFormProps) {
const [submitting, setSubmitting] = useState(false);
const [rideImage, setRideImage] = useState<string>(initialData?.image_url || '');
@@ -87,10 +120,20 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
max_speed_kmh: initialData?.max_speed_kmh || undefined,
max_height_meters: initialData?.max_height_meters || undefined,
length_meters: initialData?.length_meters || undefined,
inversions: initialData?.inversions || 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,
max_g_force: initialData?.max_g_force || undefined,
former_names: initialData?.former_names || '',
coaster_stats: initialData?.coaster_stats || '',
technical_specs: initialData?.technical_specs || ''
}
});
const selectedCategory = watch('category');
const generateSlug = (name: string) => {
return name
.toLowerCase()
@@ -279,6 +322,89 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
</div>
</div>
{/* Roller Coaster Specific Fields */}
{selectedCategory === 'roller_coaster' && (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Roller Coaster Details</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="space-y-2">
<Label>Coaster Type</Label>
<Select onValueChange={(value) => setValue('coaster_type', value)} defaultValue={initialData?.coaster_type}>
<SelectTrigger>
<SelectValue placeholder="Select type" />
</SelectTrigger>
<SelectContent>
{coasterTypes.map((type) => (
<SelectItem key={type} value={type}>
{type.charAt(0).toUpperCase() + type.slice(1)}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label>Seating Type</Label>
<Select onValueChange={(value) => setValue('seating_type', value)} defaultValue={initialData?.seating_type}>
<SelectTrigger>
<SelectValue placeholder="Select seating" />
</SelectTrigger>
<SelectContent>
{seatingTypes.map((type) => (
<SelectItem key={type} value={type}>
{type.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase())}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label>Intensity Level</Label>
<Select onValueChange={(value) => setValue('intensity_level', value)} defaultValue={initialData?.intensity_level}>
<SelectTrigger>
<SelectValue placeholder="Select intensity" />
</SelectTrigger>
<SelectContent>
{intensityLevels.map((level) => (
<SelectItem key={level} value={level}>
{level.charAt(0).toUpperCase() + level.slice(1)}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
<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>
<Input
id="drop_height_meters"
type="number"
min="0"
step="0.1"
{...register('drop_height_meters', { valueAsNumber: true })}
placeholder="e.g. 45.5"
/>
</div>
<div className="space-y-2">
<Label htmlFor="max_g_force">Max G-Force</Label>
<Input
id="max_g_force"
type="number"
min="0"
step="0.1"
{...register('max_g_force', { valueAsNumber: true })}
placeholder="e.g. 4.2"
/>
</div>
</div>
</div>
)}
{/* Technical Specifications */}
<div className="space-y-4">
<h3 className="text-lg font-semibold">Technical Specifications</h3>