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:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user