|
|
|
|
@@ -247,60 +247,7 @@ const FuelLogFormComponent: React.FC<{ onSuccess?: () => void; initial?: Partial
|
|
|
|
|
)} />
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
{/* Row 2: Date/Time | MPG/L/100km */}
|
|
|
|
|
<Grid item xs={12} sm={6}>
|
|
|
|
|
<Controller name="dateTime" control={control} render={({ field }) => (
|
|
|
|
|
<DateTimePicker
|
|
|
|
|
label="Date & Time"
|
|
|
|
|
value={field.value ? dayjs(field.value) : null}
|
|
|
|
|
onChange={(newValue) => field.onChange(newValue?.toISOString() || '')}
|
|
|
|
|
format="MM/DD/YYYY hh:mm a"
|
|
|
|
|
slotProps={{
|
|
|
|
|
textField: {
|
|
|
|
|
fullWidth: true,
|
|
|
|
|
error: !!errors.dateTime,
|
|
|
|
|
helperText: errors.dateTime?.message,
|
|
|
|
|
sx: {
|
|
|
|
|
'& .MuiOutlinedInput-root': {
|
|
|
|
|
minHeight: '56px',
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
)} />
|
|
|
|
|
</Grid>
|
|
|
|
|
<Grid item xs={12} sm={6}>
|
|
|
|
|
<TextField
|
|
|
|
|
label={`${userSettings?.unitSystem === 'metric' ? 'L/100km' : 'MPG'}`}
|
|
|
|
|
value={calculatedEfficiency > 0 ? calculatedEfficiency.toFixed(3) : ''}
|
|
|
|
|
fullWidth
|
|
|
|
|
InputProps={{
|
|
|
|
|
readOnly: true,
|
|
|
|
|
sx: (theme) => ({
|
|
|
|
|
backgroundColor: 'grey.50',
|
|
|
|
|
...theme.applyStyles('dark', {
|
|
|
|
|
backgroundColor: '#4C4E4D',
|
|
|
|
|
}),
|
|
|
|
|
'& .MuiOutlinedInput-input': {
|
|
|
|
|
cursor: 'default',
|
|
|
|
|
color: 'inherit',
|
|
|
|
|
...theme.applyStyles('dark', {
|
|
|
|
|
color: '#F2F3F6',
|
|
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
}}
|
|
|
|
|
helperText="Calculated from distance ÷ fuel amount"
|
|
|
|
|
sx={{
|
|
|
|
|
'& .MuiOutlinedInput-root': {
|
|
|
|
|
minHeight: '56px',
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
{/* Row 3: Odometer | Distance Input Method */}
|
|
|
|
|
{/* Row 2: Mileage (Trip Distance / Odometer) | Input Method Toggle */}
|
|
|
|
|
<Grid item xs={12} sm={6}>
|
|
|
|
|
<Controller name={useOdometer ? 'odometerReading' : 'tripDistance'} control={control} render={({ field }) => (
|
|
|
|
|
<DistanceInput type={useOdometer ? 'odometer' : 'trip'} value={field.value as any} onChange={field.onChange as any} unitSystem={userSettings?.unitSystem} error={useOdometer ? (errors.odometerReading?.message as any) : (errors.tripDistance?.message as any)} />
|
|
|
|
|
@@ -342,11 +289,21 @@ const FuelLogFormComponent: React.FC<{ onSuccess?: () => void; initial?: Partial
|
|
|
|
|
</ToggleButton>
|
|
|
|
|
</ToggleButtonGroup>
|
|
|
|
|
</Grid>
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
<Controller name="fuelType" control={control} render={({ field: fuelTypeField }) => (
|
|
|
|
|
<Controller name="fuelGrade" control={control} render={({ field: fuelGradeField }) => (
|
|
|
|
|
<FuelTypeSelector fuelType={fuelTypeField.value} fuelGrade={fuelGradeField.value as any} onFuelTypeChange={fuelTypeField.onChange} onFuelGradeChange={fuelGradeField.onChange as any} error={(errors.fuelType?.message as any) || (errors.fuelGrade?.message as any)} />
|
|
|
|
|
)} />
|
|
|
|
|
|
|
|
|
|
{/* Row 3: Cost Per Gallon | Fuel Amount */}
|
|
|
|
|
<Grid item xs={12} sm={6}>
|
|
|
|
|
<Controller name="costPerUnit" control={control} render={({ field }) => (
|
|
|
|
|
<TextField
|
|
|
|
|
{...field}
|
|
|
|
|
value={field.value ?? ''}
|
|
|
|
|
onChange={(e) => field.onChange(e.target.value)}
|
|
|
|
|
label={`Cost Per ${userSettings?.unitSystem === 'imperial' ? 'Gallon' : 'Liter'}`}
|
|
|
|
|
type="number"
|
|
|
|
|
inputProps={{ step: 0.001, min: 0.001, inputMode: 'decimal' }}
|
|
|
|
|
fullWidth
|
|
|
|
|
error={!!errors.costPerUnit}
|
|
|
|
|
helperText={errors.costPerUnit?.message}
|
|
|
|
|
/>
|
|
|
|
|
)} />
|
|
|
|
|
</Grid>
|
|
|
|
|
<Grid item xs={12} sm={6}>
|
|
|
|
|
@@ -357,31 +314,27 @@ const FuelLogFormComponent: React.FC<{ onSuccess?: () => void; initial?: Partial
|
|
|
|
|
onChange={(e) => field.onChange(e.target.value)}
|
|
|
|
|
label={`Fuel Amount (${userSettings?.unitSystem === 'imperial' ? 'gallons' : 'liters'})`}
|
|
|
|
|
type="number"
|
|
|
|
|
inputProps={{ step: 0.001, min: 0.001 }}
|
|
|
|
|
inputProps={{ step: 0.001, min: 0.001, inputMode: 'decimal' }}
|
|
|
|
|
fullWidth
|
|
|
|
|
error={!!errors.fuelUnits}
|
|
|
|
|
helperText={errors.fuelUnits?.message}
|
|
|
|
|
/>
|
|
|
|
|
)} />
|
|
|
|
|
</Grid>
|
|
|
|
|
<Grid item xs={12} sm={6}>
|
|
|
|
|
<Controller name="costPerUnit" control={control} render={({ field }) => (
|
|
|
|
|
<TextField
|
|
|
|
|
{...field}
|
|
|
|
|
value={field.value ?? ''}
|
|
|
|
|
onChange={(e) => 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}
|
|
|
|
|
/>
|
|
|
|
|
)} />
|
|
|
|
|
</Grid>
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
<CostCalculator fuelUnits={fuelUnits} costPerUnit={costPerUnit} calculatedCost={calculatedCost} />
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
{/* Row 4: Fuel Type / Fuel Grade (grade options filtered by type) */}
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
<Controller name="fuelType" control={control} render={({ field: fuelTypeField }) => (
|
|
|
|
|
<Controller name="fuelGrade" control={control} render={({ field: fuelGradeField }) => (
|
|
|
|
|
<FuelTypeSelector fuelType={fuelTypeField.value} fuelGrade={fuelGradeField.value as any} onFuelTypeChange={fuelTypeField.onChange} onFuelGradeChange={fuelGradeField.onChange as any} error={(errors.fuelType?.message as any) || (errors.fuelGrade?.message as any)} />
|
|
|
|
|
)} />
|
|
|
|
|
)} />
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
{/* Row 5: Location */}
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
<Controller name="locationData" control={control} render={({ field }) => (
|
|
|
|
|
<StationPicker
|
|
|
|
|
@@ -392,11 +345,68 @@ const FuelLogFormComponent: React.FC<{ onSuccess?: () => void; initial?: Partial
|
|
|
|
|
/>
|
|
|
|
|
)} />
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
{/* Row 6: MPG/L/100km (calculated, read-only) */}
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
<TextField
|
|
|
|
|
label={`${userSettings?.unitSystem === 'metric' ? 'L/100km' : 'MPG'}`}
|
|
|
|
|
value={calculatedEfficiency > 0 ? calculatedEfficiency.toFixed(3) : ''}
|
|
|
|
|
fullWidth
|
|
|
|
|
InputProps={{
|
|
|
|
|
readOnly: true,
|
|
|
|
|
sx: (theme) => ({
|
|
|
|
|
backgroundColor: 'grey.50',
|
|
|
|
|
...theme.applyStyles('dark', {
|
|
|
|
|
backgroundColor: '#4C4E4D',
|
|
|
|
|
}),
|
|
|
|
|
'& .MuiOutlinedInput-input': {
|
|
|
|
|
cursor: 'default',
|
|
|
|
|
color: 'inherit',
|
|
|
|
|
...theme.applyStyles('dark', {
|
|
|
|
|
color: '#F2F3F6',
|
|
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
}}
|
|
|
|
|
helperText="Calculated from distance ÷ fuel amount"
|
|
|
|
|
sx={{
|
|
|
|
|
'& .MuiOutlinedInput-root': {
|
|
|
|
|
minHeight: '56px',
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
{/* Row 7: Notes */}
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
<Controller name="notes" control={control} render={({ field }) => (
|
|
|
|
|
<TextField {...field} label="Notes (optional)" multiline rows={3} fullWidth error={!!errors.notes} helperText={errors.notes?.message} />
|
|
|
|
|
)} />
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
{/* Row 8: Date & Time (defaults to now, least-edited field) */}
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
<Controller name="dateTime" control={control} render={({ field }) => (
|
|
|
|
|
<DateTimePicker
|
|
|
|
|
label="Date & Time"
|
|
|
|
|
value={field.value ? dayjs(field.value) : null}
|
|
|
|
|
onChange={(newValue) => field.onChange(newValue?.toISOString() || '')}
|
|
|
|
|
format="MM/DD/YYYY hh:mm a"
|
|
|
|
|
slotProps={{
|
|
|
|
|
textField: {
|
|
|
|
|
fullWidth: true,
|
|
|
|
|
error: !!errors.dateTime,
|
|
|
|
|
helperText: errors.dateTime?.message,
|
|
|
|
|
sx: {
|
|
|
|
|
'& .MuiOutlinedInput-root': {
|
|
|
|
|
minHeight: '56px',
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
)} />
|
|
|
|
|
</Grid>
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
<Box display="flex" gap={2} justifyContent="flex-end">
|
|
|
|
|
<Button type="submit" variant="contained" disabled={!isValid || isLoading} startIcon={isLoading ? <CircularProgress size={18} /> : undefined}>Add Fuel Log</Button>
|
|
|
|
|
|