import React, { useMemo, useState } from 'react'; import { Card, CardContent, Typography, List, ListItem, ListItemText, Chip, Box, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button, useTheme, useMediaQuery } from '@mui/material'; import { Edit, Delete } from '@mui/icons-material'; import { FuelLogResponse } from '../types/fuel-logs.types'; import { fuelLogsApi } from '../api/fuel-logs.api'; import { useUnits } from '../../../core/units/UnitsContext'; interface FuelLogsListProps { logs?: FuelLogResponse[]; onEdit?: (log: FuelLogResponse) => void; onDelete?: (logId: string) => void; } export const FuelLogsList: React.FC = ({ logs, onEdit, onDelete }) => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('sm')); const { unitSystem, convertDistance, convertVolume } = useUnits(); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [logToDelete, setLogToDelete] = useState(null); const [isDeleting, setIsDeleting] = useState(false); // Precompute previous odometer per log for delta calculations const prevOdoById = useMemo(() => { const map = new Map(); if (!Array.isArray(logs)) return map; const asc = [...logs].sort((a, b) => new Date(a.dateTime).getTime() - new Date(b.dateTime).getTime()); let lastOdo: number | undefined = undefined; for (const l of asc) { map.set(l.id, lastOdo); if (typeof l.odometerReading === 'number' && !isNaN(l.odometerReading)) { lastOdo = l.odometerReading; } } return map; }, [logs]); const handleDeleteClick = (log: FuelLogResponse) => { setLogToDelete(log); setDeleteDialogOpen(true); }; const handleDeleteConfirm = async () => { if (!logToDelete) return; try { setIsDeleting(true); await fuelLogsApi.delete(logToDelete.id); onDelete?.(logToDelete.id); setDeleteDialogOpen(false); setLogToDelete(null); } catch (error) { console.error('Failed to delete fuel log:', error); // TODO: Show error notification } finally { setIsDeleting(false); } }; const handleDeleteCancel = () => { setDeleteDialogOpen(false); setLogToDelete(null); }; // Defensive check for logs data if (!Array.isArray(logs) || logs.length === 0) { return ( No fuel logs yet. ); } return ( <> {logs.map((log) => { // Defensive checks for each log entry if (!log || !log.id) { console.warn('[FuelLogsList] Invalid log entry:', log); return null; } try { // Safe date formatting const dateText = log.dateTime ? new Date(log.dateTime).toLocaleString() : 'Unknown date'; // Safe cost formatting const totalCost = typeof log.totalCost === 'number' ? log.totalCost.toFixed(2) : '0.00'; // Safe fuel units and cost per unit const fuelUnits = typeof log.fuelUnits === 'number' ? log.fuelUnits.toFixed(3) : '0.000'; const costPerUnit = typeof log.costPerUnit === 'number' ? log.costPerUnit.toFixed(3) : '0.000'; // Safe distance display const distanceText = log.odometerReading ? `Odo: ${log.odometerReading}` : log.tripDistance ? `Trip: ${log.tripDistance}` : 'No distance'; // Compute local efficiency if not provided let localEffLabel: string | null = null; try { const gallons = typeof log.fuelUnits === 'number' ? log.fuelUnits : undefined; let miles: number | undefined = typeof log.tripDistance === 'number' && !isNaN(log.tripDistance) ? log.tripDistance : undefined; if (miles === undefined && typeof log.odometerReading === 'number') { const prev = prevOdoById.get(log.id); if (typeof prev === 'number' && log.odometerReading > prev) { miles = log.odometerReading - prev; } } if (typeof miles === 'number' && typeof gallons === 'number' && gallons > 0) { if (unitSystem === 'metric') { const km = convertDistance(miles); const liters = convertVolume(gallons); if (liters > 0) localEffLabel = `${(km / liters).toFixed(1)} km/L`; } else { localEffLabel = `${(miles / gallons).toFixed(1)} MPG`; } } } catch {} return ( {(log.efficiency && typeof log.efficiency === 'number' && !isNaN(log.efficiency) && log.efficiencyLabel) || localEffLabel ? ( ) : null} {onEdit && ( onEdit(log)} sx={{ color: 'primary.main', '&:hover': { backgroundColor: 'primary.main', color: 'white' }, minWidth: isMobile ? 48 : 'auto', minHeight: isMobile ? 48 : 'auto', ...(isMobile && { border: '1px solid', borderColor: 'primary.main', borderRadius: 2 }) }} > )} {onDelete && ( handleDeleteClick(log)} sx={{ color: 'error.main', '&:hover': { backgroundColor: 'error.main', color: 'white' }, minWidth: isMobile ? 48 : 'auto', minHeight: isMobile ? 48 : 'auto', ...(isMobile && { border: '1px solid', borderColor: 'error.main', borderRadius: 2 }) }} > )} ); } catch (error) { console.error('[FuelLogsList] Error rendering log:', log, error); return ( ); } }).filter(Boolean)} {/* Delete Confirmation Dialog */} Delete Fuel Log Are you sure you want to delete this fuel log entry? This action cannot be undone. {logToDelete && ( {new Date(logToDelete.dateTime).toLocaleString()} - ${logToDelete.totalCost.toFixed(2)} )} ); };