Files
motovaultpro/frontend/src/features/documents/components/DeleteDocumentConfirmDialog.tsx
Eric Gullickson bdb329f7c3 feat: add context-aware document delete from vehicle screen (refs #31)
- Created DeleteDocumentConfirmDialog with context-aware messaging:
  - Primary vehicle with no shares: Full delete
  - Shared vehicle: Remove association only
  - Primary vehicle with shares: Full delete (affects all)
- Integrated documents display in VehicleDetailPage records table
- Added delete button per document with 44px touch target
- Document deletion uses appropriate backend calls based on context
- Mobile-friendly dialog with responsive design

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 19:41:52 -06:00

138 lines
4.2 KiB
TypeScript

/**
* @ai-summary Context-aware document delete confirmation dialog
* Shows different messages based on whether document is being removed from vehicle or fully deleted
*/
import React from 'react';
import {
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Button,
Typography,
Box,
useMediaQuery,
useTheme,
} from '@mui/material';
import WarningAmberIcon from '@mui/icons-material/WarningAmber';
import type { DocumentRecord } from '../types/documents.types';
export interface DeleteDocumentConfirmDialogProps {
open: boolean;
onClose: () => void;
onConfirm: (fullDelete: boolean) => void;
document: DocumentRecord | null;
vehicleId: string | null;
}
export const DeleteDocumentConfirmDialog: React.FC<DeleteDocumentConfirmDialogProps> = ({
open,
onClose,
onConfirm,
document,
vehicleId,
}) => {
const theme = useTheme();
const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm'));
if (!document || !vehicleId) {
return null;
}
// Determine delete context
const isPrimaryVehicle = document.vehicleId === vehicleId;
const isSharedVehicle = document.sharedVehicleIds.includes(vehicleId);
const sharedCount = document.sharedVehicleIds.length;
let title: string;
let message: string;
let fullDelete: boolean;
let actionText: string;
if (isPrimaryVehicle && sharedCount === 0) {
// Primary vehicle with no shares: Full delete
title = 'Delete Document?';
message = 'This will permanently delete this document. This action cannot be undone.';
fullDelete = true;
actionText = 'Delete';
} else if (isSharedVehicle) {
// Shared vehicle: Remove association only
title = 'Remove Document from Vehicle?';
message = `This will remove the document from this vehicle. The document will remain shared with ${sharedCount - 1 === 1 ? '1 other vehicle' : `${sharedCount - 1} other vehicles`}.`;
fullDelete = false;
actionText = 'Remove';
} else if (isPrimaryVehicle && sharedCount > 0) {
// Primary vehicle with shares: Full delete (affects all)
title = 'Delete Document?';
message = `This document is shared with ${sharedCount === 1 ? '1 other vehicle' : `${sharedCount} other vehicles`}. Deleting it will remove it from all vehicles. This action cannot be undone.`;
fullDelete = true;
actionText = 'Delete';
} else {
// Fallback case (should not happen)
title = 'Delete Document?';
message = 'This will delete this document. This action cannot be undone.';
fullDelete = true;
actionText = 'Delete';
}
const handleConfirm = () => {
onConfirm(fullDelete);
};
return (
<Dialog
open={open}
onClose={onClose}
maxWidth="sm"
fullWidth
fullScreen={isSmallScreen}
PaperProps={{
sx: {
borderRadius: isSmallScreen ? 0 : 2,
},
}}
>
<DialogTitle sx={{ pb: 1 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<WarningAmberIcon color="warning" />
<Typography variant="h6" component="span" sx={{ fontWeight: 600 }}>
{title}
</Typography>
</Box>
</DialogTitle>
<DialogContent>
<Typography variant="body1" sx={{ color: 'text.secondary', mt: 1 }}>
{message}
</Typography>
<Box sx={{ mt: 2, p: 2, bgcolor: 'grey.100', borderRadius: 1 }}>
<Typography variant="body2" sx={{ fontWeight: 600, mb: 0.5 }}>
{document.title}
</Typography>
<Typography variant="caption" sx={{ color: 'text.secondary' }}>
{document.documentType.charAt(0).toUpperCase() + document.documentType.slice(1)}
{document.expirationDate && ` • Expires: ${new Date(document.expirationDate).toLocaleDateString()}`}
</Typography>
</Box>
</DialogContent>
<DialogActions sx={{ px: 3, pb: 2 }}>
<Button
onClick={onClose}
variant="outlined"
sx={{ minWidth: 100, minHeight: 44 }}
>
Cancel
</Button>
<Button
onClick={handleConfirm}
variant="contained"
color={fullDelete ? 'error' : 'primary'}
sx={{ minWidth: 100, minHeight: 44 }}
>
{actionText}
</Button>
</DialogActions>
</Dialog>
);
};