import React, { useEffect, useMemo, useState, useRef, memo } from 'react'; import { useForm, Controller } from 'react-hook-form'; import { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; import { Grid, Card, CardHeader, CardContent, TextField, Switch, FormControlLabel, Box, Button, CircularProgress } from '@mui/material'; import { VehicleSelector } from './VehicleSelector'; import { DistanceInput } from './DistanceInput'; import { FuelTypeSelector } from './FuelTypeSelector'; import { UnitSystemDisplay } from './UnitSystemDisplay'; import { LocationInput } from './LocationInput'; import { CostCalculator } from './CostCalculator'; import { useFuelLogs } from '../hooks/useFuelLogs'; import { useUserSettings } from '../hooks/useUserSettings'; import { CreateFuelLogRequest, FuelType } from '../types/fuel-logs.types'; const schema = z.object({ vehicleId: z.string().uuid(), dateTime: z.string().min(1), odometerReading: z.coerce.number().positive().optional(), tripDistance: z.coerce.number().positive().optional(), fuelType: z.nativeEnum(FuelType), fuelGrade: z.union([z.string(), z.null()]).optional(), fuelUnits: z.coerce.number().positive(), costPerUnit: z.coerce.number().positive(), locationData: z.any().optional(), notes: z.string().max(500).optional(), }).refine((d) => (d.odometerReading && d.odometerReading > 0) || (d.tripDistance && d.tripDistance > 0), { message: 'Either odometer reading or trip distance is required' }).refine((d) => !(d.odometerReading && d.tripDistance), { message: 'Cannot specify both odometer reading and trip distance' }); const FuelLogFormComponent: React.FC<{ onSuccess?: () => void; initial?: Partial }> = ({ onSuccess, initial }) => { const { userSettings } = useUserSettings(); const { createFuelLog, isLoading } = useFuelLogs(); const [useOdometer, setUseOdometer] = useState(false); const formInitialized = useRef(false); const { control, handleSubmit, watch, setValue, formState: { errors, isValid } } = useForm({ resolver: zodResolver(schema), mode: 'onChange', defaultValues: { dateTime: new Date().toISOString().slice(0, 16), fuelType: FuelType.GASOLINE, ...initial } as any }); // DEBUG: Log component renders and form state console.log('[FuelLogForm] Render - formInitialized:', formInitialized.current, 'isLoading:', isLoading); // Prevent form reset after initial load useEffect(() => { if (!formInitialized.current) { formInitialized.current = true; console.log('[FuelLogForm] Form initialized'); } }, []); // DEBUG: Watch for form value changes const vehicleId = watch('vehicleId'); useEffect(() => { console.log('[FuelLogForm] Vehicle ID changed:', vehicleId); }, [vehicleId]); const watched = watch(['fuelUnits', 'costPerUnit']); const [fuelUnitsRaw, costPerUnitRaw] = watched as [string | number | undefined, string | number | undefined]; // Convert to numbers for calculation const fuelUnits = typeof fuelUnitsRaw === 'string' ? parseFloat(fuelUnitsRaw) : fuelUnitsRaw; const costPerUnit = typeof costPerUnitRaw === 'string' ? parseFloat(costPerUnitRaw) : costPerUnitRaw; const calculatedCost = useMemo(() => { const units = fuelUnits && !isNaN(fuelUnits) ? fuelUnits : 0; const cost = costPerUnit && !isNaN(costPerUnit) ? costPerUnit : 0; return units > 0 && cost > 0 ? units * cost : 0; }, [fuelUnits, costPerUnit]); const onSubmit = async (data: CreateFuelLogRequest) => { const payload: CreateFuelLogRequest = { ...data, odometerReading: useOdometer ? data.odometerReading : undefined, tripDistance: useOdometer ? undefined : data.tripDistance, }; await createFuelLog(payload); onSuccess?.(); }; useEffect(() => { if (useOdometer) setValue('tripDistance', undefined as any); else setValue('odometerReading', undefined as any); }, [useOdometer, setValue]); return ( } />
( )} /> ( )} /> setUseOdometer(e.target.checked)} />} label={`Use ${useOdometer ? 'Odometer' : 'Trip Distance'}`} /> ( )} /> ( ( )} /> )} /> ( field.onChange(e.target.value)} label={`Fuel Amount (${userSettings?.unitSystem === 'imperial' ? 'gallons' : 'liters'})`} type="number" inputProps={{ step: 0.001, min: 0.001 }} fullWidth error={!!errors.fuelUnits} helperText={errors.fuelUnits?.message} /> )} /> ( field.onChange(e.target.value)} label={`Cost Per ${userSettings?.unitSystem === 'imperial' ? 'Gallon' : 'Liter'}`} type="number" inputProps={{ step: 0.001, min: 0.001 }} fullWidth error={!!errors.costPerUnit} helperText={errors.costPerUnit?.message} /> )} /> ( )} /> ( )} />
); }; export const FuelLogForm = memo(FuelLogFormComponent);