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:
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -1,12 +1,12 @@
|
||||
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 { FuelLogForm } from '../components/FuelLogForm';
|
||||
import { FuelLogsList } from '../components/FuelLogsList';
|
||||
import { FuelLogEditDialog } from '../components/FuelLogEditDialog';
|
||||
import { AddFuelLogDialog } from '../components/AddFuelLogDialog';
|
||||
import { useFuelLogs } from '../hooks/useFuelLogs';
|
||||
import { FuelStatsCard } from '../components/FuelStatsCard';
|
||||
import { FormSuspense } from '../../../components/SuspenseWrappers';
|
||||
import { FuelLogResponse, UpdateFuelLogRequest } from '../types/fuel-logs.types';
|
||||
import { fuelLogsApi } from '../api/fuel-logs.api';
|
||||
|
||||
@@ -14,9 +14,7 @@ export const FuelLogsPage: React.FC = () => {
|
||||
const { fuelLogs, isLoading, error } = useFuelLogs();
|
||||
const queryClient = useQueryClient();
|
||||
const [editingLog, setEditingLog] = useState<FuelLogResponse | null>(null);
|
||||
|
||||
// DEBUG: Log page renders
|
||||
console.log('[FuelLogsPage] Render - fuel logs count:', fuelLogs?.length, 'isLoading:', isLoading, 'error:', !!error);
|
||||
const [showAddDialog, setShowAddDialog] = useState(false);
|
||||
|
||||
const handleEdit = (log: FuelLogResponse) => {
|
||||
setEditingLog(log);
|
||||
@@ -24,9 +22,6 @@ export const FuelLogsPage: React.FC = () => {
|
||||
|
||||
const handleDelete = async (_logId: string) => {
|
||||
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'] });
|
||||
} catch (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) => {
|
||||
try {
|
||||
console.log('[FuelLogsPage] handleSaveEdit called - using targeted query updates');
|
||||
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'] });
|
||||
setEditingLog(null);
|
||||
} catch (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 (
|
||||
<FormSuspense>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={6}>
|
||||
<FuelLogForm />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<Typography variant="h6" gutterBottom>Summary</Typography>
|
||||
<Box>
|
||||
{/* Header with Add button */}
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
|
||||
<Typography variant="h5" sx={{ fontWeight: 600 }}>Fuel Logs</Typography>
|
||||
<MuiButton
|
||||
variant="contained"
|
||||
startIcon={<AddIcon />}
|
||||
onClick={() => setShowAddDialog(true)}
|
||||
>
|
||||
Add Fuel Log
|
||||
</MuiButton>
|
||||
</Box>
|
||||
|
||||
{/* Summary Stats */}
|
||||
<Box sx={{ mb: 3 }}>
|
||||
<FuelStatsCard logs={fuelLogs} />
|
||||
<Typography variant="h6" sx={{ mt: 3 }} gutterBottom>Recent Fuel Logs</Typography>
|
||||
</Box>
|
||||
|
||||
{/* Fuel Logs List */}
|
||||
<FuelLogsList
|
||||
logs={fuelLogs}
|
||||
onEdit={handleEdit}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{/* Add Dialog */}
|
||||
<AddFuelLogDialog
|
||||
open={showAddDialog}
|
||||
onClose={() => setShowAddDialog(false)}
|
||||
/>
|
||||
|
||||
{/* Edit Dialog */}
|
||||
<FuelLogEditDialog
|
||||
@@ -102,6 +108,6 @@ export const FuelLogsPage: React.FC = () => {
|
||||
onClose={handleCloseEdit}
|
||||
onSave={handleSaveEdit}
|
||||
/>
|
||||
</FormSuspense>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user