Checkpoint: Ajout de boutons Modifier et Supprimer sur chaque ligne de la liste des factures. Le bouton Modifier redirige vers la page de détail, le bouton Supprimer affiche une boîte de dialogue de confirmation avant suppression définitive.

This commit is contained in:
Manus
2026-02-11 09:04:49 -05:00
parent b93c31619f
commit e217ac06ce
2 changed files with 81 additions and 1 deletions

View File

@@ -5,6 +5,16 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
Table,
TableBody,
@@ -14,7 +24,7 @@ import {
TableRow,
} from "@/components/ui/table";
import { trpc } from "@/lib/trpc";
import { Search, FileText, Download, FileSpreadsheet, Trash2 } from "lucide-react";
import { Search, FileText, Download, FileSpreadsheet, Trash2, Edit, Trash } from "lucide-react";
import * as XLSX from 'xlsx';
import { toast } from "sonner";
import { useLocation } from "wouter";
@@ -24,6 +34,8 @@ export default function Invoices() {
const [searchQuery, setSearchQuery] = useState("");
const [selectedIds, setSelectedIds] = useState<number[]>([]);
const [statusFilter, setStatusFilter] = useState<string>("all");
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
const [invoiceToDelete, setInvoiceToDelete] = useState<number | null>(null);
const { data: invoices, isLoading } = trpc.invoices.list.useQuery();
const utils = trpc.useUtils();
@@ -77,6 +89,18 @@ export default function Invoices() {
},
});
const deleteMutation = trpc.invoices.delete.useMutation({
onSuccess: () => {
toast.success("Facture supprimée avec succès");
utils.invoices.list.invalidate();
setDeleteDialogOpen(false);
setInvoiceToDelete(null);
},
onError: (error) => {
toast.error(error.message || "Erreur lors de la suppression");
},
});
const filteredInvoices = invoices?.filter((inv) => {
// Filter by search query
if (searchQuery) {
@@ -309,6 +333,7 @@ export default function Invoices() {
<TableHead>Ventilation</TableHead>
<TableHead>Score</TableHead>
<TableHead>Statut</TableHead>
<TableHead className="w-32">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
@@ -345,6 +370,29 @@ export default function Invoices() {
<TableCell className="text-sm">{invoice.ventilationComptable || "-"}</TableCell>
<TableCell>{getQualityBadge(invoice.qualityScore)}</TableCell>
<TableCell>{getExportStatusBadge(invoice.exportStatus || "not_exported")}</TableCell>
<TableCell>
<div className="flex gap-2">
<Button
size="sm"
variant="outline"
onClick={() => setLocation(`/invoices/${invoice.id}`)}
className="h-8 px-2"
>
<Edit className="h-4 w-4" />
</Button>
<Button
size="sm"
variant="outline"
onClick={() => {
setInvoiceToDelete(invoice.id);
setDeleteDialogOpen(true);
}}
className="h-8 px-2 text-red-600 hover:text-red-700 hover:bg-red-50"
>
<Trash className="h-4 w-4" />
</Button>
</div>
</TableCell>
</TableRow>
);
})}
@@ -373,6 +421,31 @@ export default function Invoices() {
</div>
)}
</div>
{/* Delete Confirmation Dialog */}
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Êtes-vous sûr de vouloir supprimer cette facture ?</AlertDialogTitle>
<AlertDialogDescription>
Cette action est irréversible. La facture sera définitivement supprimée de la base de données.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel onClick={() => setInvoiceToDelete(null)}>Annuler</AlertDialogCancel>
<AlertDialogAction
onClick={() => {
if (invoiceToDelete) {
deleteMutation.mutate({ id: invoiceToDelete });
}
}}
className="bg-red-600 hover:bg-red-700"
>
Supprimer
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</DashboardLayout>
);
}

View File

@@ -215,3 +215,10 @@
- [x] Modifier InvoiceDetail.tsx pour charger les listes depuis la base de données
- [x] Remplacer les valeurs codées en dur par des appels tRPC
- [x] Tester que les valeurs personnalisées apparaissent dans les menus déroulants
## Boutons Modifier et Supprimer dans la liste des factures
- [x] Ajouter une colonne "Actions" dans le tableau des factures
- [x] Ajouter un bouton "Modifier" qui redirige vers InvoiceDetail
- [x] Ajouter un bouton "Supprimer" avec confirmation (AlertDialog)
- [x] Utiliser la route tRPC existante pour supprimer une facture
- [x] Tester la suppression avec confirmation