chore: restructure Fuel Logs to list-first with add dialog (refs #168)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Eric Gullickson
2026-02-13 19:49:46 -06:00
parent f2b20aab1a
commit e4be744643
2 changed files with 80 additions and 30 deletions

View File

@@ -0,0 +1,44 @@
/**
* @ai-summary Dialog wrapper for FuelLogForm to create new fuel logs
*/
import React from 'react';
import { Dialog, DialogTitle, DialogContent, IconButton, useMediaQuery } from '@mui/material';
import CloseIcon from '@mui/icons-material/Close';
import { FuelLogForm } from './FuelLogForm';
interface AddFuelLogDialogProps {
open: boolean;
onClose: () => void;
}
export const AddFuelLogDialog: React.FC<AddFuelLogDialogProps> = ({ open, onClose }) => {
const isSmallScreen = useMediaQuery('(max-width:600px)');
return (
<Dialog
open={open}
onClose={onClose}
maxWidth="sm"
fullWidth
fullScreen={isSmallScreen}
PaperProps={{
sx: { maxHeight: isSmallScreen ? '100%' : '90vh' },
}}
>
<DialogTitle sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
Log Fuel
<IconButton
aria-label="close"
onClick={onClose}
sx={{ minWidth: 44, minHeight: 44 }}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent sx={{ p: { xs: 1, sm: 2 } }}>
<FuelLogForm onSuccess={onClose} />
</DialogContent>
</Dialog>
);
};

View File

@@ -1,12 +1,12 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Grid, Typography, Box } from '@mui/material'; import { Typography, Box, Button as MuiButton } from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { FuelLogForm } from '../components/FuelLogForm';
import { FuelLogsList } from '../components/FuelLogsList'; import { FuelLogsList } from '../components/FuelLogsList';
import { FuelLogEditDialog } from '../components/FuelLogEditDialog'; import { FuelLogEditDialog } from '../components/FuelLogEditDialog';
import { AddFuelLogDialog } from '../components/AddFuelLogDialog';
import { useFuelLogs } from '../hooks/useFuelLogs'; import { useFuelLogs } from '../hooks/useFuelLogs';
import { FuelStatsCard } from '../components/FuelStatsCard'; import { FuelStatsCard } from '../components/FuelStatsCard';
import { FormSuspense } from '../../../components/SuspenseWrappers';
import { FuelLogResponse, UpdateFuelLogRequest } from '../types/fuel-logs.types'; import { FuelLogResponse, UpdateFuelLogRequest } from '../types/fuel-logs.types';
import { fuelLogsApi } from '../api/fuel-logs.api'; import { fuelLogsApi } from '../api/fuel-logs.api';
@@ -14,9 +14,7 @@ export const FuelLogsPage: React.FC = () => {
const { fuelLogs, isLoading, error } = useFuelLogs(); const { fuelLogs, isLoading, error } = useFuelLogs();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const [editingLog, setEditingLog] = useState<FuelLogResponse | null>(null); const [editingLog, setEditingLog] = useState<FuelLogResponse | null>(null);
const [showAddDialog, setShowAddDialog] = useState(false);
// DEBUG: Log page renders
console.log('[FuelLogsPage] Render - fuel logs count:', fuelLogs?.length, 'isLoading:', isLoading, 'error:', !!error);
const handleEdit = (log: FuelLogResponse) => { const handleEdit = (log: FuelLogResponse) => {
setEditingLog(log); setEditingLog(log);
@@ -24,9 +22,6 @@ export const FuelLogsPage: React.FC = () => {
const handleDelete = async (_logId: string) => { const handleDelete = async (_logId: string) => {
try { try {
console.log('[FuelLogsPage] handleDelete called - using targeted query updates');
// Use targeted invalidation instead of broad invalidation
// This prevents unnecessary re-renders of the form
queryClient.refetchQueries({ queryKey: ['fuelLogs', 'all'] }); queryClient.refetchQueries({ queryKey: ['fuelLogs', 'all'] });
} catch (error) { } catch (error) {
console.error('Failed to refresh fuel logs after delete:', error); console.error('Failed to refresh fuel logs after delete:', error);
@@ -35,15 +30,12 @@ export const FuelLogsPage: React.FC = () => {
const handleSaveEdit = async (id: string, data: UpdateFuelLogRequest) => { const handleSaveEdit = async (id: string, data: UpdateFuelLogRequest) => {
try { try {
console.log('[FuelLogsPage] handleSaveEdit called - using targeted query updates');
await fuelLogsApi.update(id, data); await fuelLogsApi.update(id, data);
// Use targeted refetch instead of broad invalidation
// This prevents unnecessary re-renders of the form
queryClient.refetchQueries({ queryKey: ['fuelLogs', 'all'] }); queryClient.refetchQueries({ queryKey: ['fuelLogs', 'all'] });
setEditingLog(null); setEditingLog(null);
} catch (error) { } catch (error) {
console.error('Failed to update fuel log:', error); console.error('Failed to update fuel log:', error);
throw error; // Re-throw to let the dialog handle the error throw error;
} }
}; };
@@ -78,22 +70,36 @@ export const FuelLogsPage: React.FC = () => {
} }
return ( return (
<FormSuspense> <Box>
<Grid container spacing={2}> {/* Header with Add button */}
<Grid item xs={12} md={6}> <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
<FuelLogForm /> <Typography variant="h5" sx={{ fontWeight: 600 }}>Fuel Logs</Typography>
</Grid> <MuiButton
<Grid item xs={12} md={6}> variant="contained"
<Typography variant="h6" gutterBottom>Summary</Typography> startIcon={<AddIcon />}
<FuelStatsCard logs={fuelLogs} /> onClick={() => setShowAddDialog(true)}
<Typography variant="h6" sx={{ mt: 3 }} gutterBottom>Recent Fuel Logs</Typography> >
<FuelLogsList Add Fuel Log
logs={fuelLogs} </MuiButton>
onEdit={handleEdit} </Box>
onDelete={handleDelete}
/> {/* Summary Stats */}
</Grid> <Box sx={{ mb: 3 }}>
</Grid> <FuelStatsCard logs={fuelLogs} />
</Box>
{/* Fuel Logs List */}
<FuelLogsList
logs={fuelLogs}
onEdit={handleEdit}
onDelete={handleDelete}
/>
{/* Add Dialog */}
<AddFuelLogDialog
open={showAddDialog}
onClose={() => setShowAddDialog(false)}
/>
{/* Edit Dialog */} {/* Edit Dialog */}
<FuelLogEditDialog <FuelLogEditDialog
@@ -102,6 +108,6 @@ export const FuelLogsPage: React.FC = () => {
onClose={handleCloseEdit} onClose={handleCloseEdit}
onSave={handleSaveEdit} onSave={handleSaveEdit}
/> />
</FormSuspense> </Box>
); );
}; };