import { useState } from "react"; import { trpc } from "@/lib/trpc"; import DashboardLayout from "@/components/DashboardLayout"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { toast } from "sonner"; import { Loader2, CheckSquare, Search, Trash2, FolderOpen, Monitor, Calendar, User, Download, RefreshCw, } from "lucide-react"; // Helper : télécharge un PDF annoté BAP depuis son URL de stockage // pdfUrl peut être : '/storage/2026-04/BAP_xxx.pdf' ou '/storage/BAP_xxx.pdf' // Nommage : AAAA-MM-JJ - Fournisseur - N°Facture.pdf function downloadBapPdf( pdfUrl: string, supplierName?: string | null, invoiceNumber?: string | null, validatedAt?: Date | string | null ) { const fallback = pdfUrl.split('/').pop() || 'BAP.pdf'; // Construire le nom de fichier : date - fournisseur - numero.pdf const datePart = validatedAt ? new Date(validatedAt).toLocaleDateString('fr-CA') // format AAAA-MM-JJ : ''; const supplierPart = (supplierName || '').replace(/[^a-zA-Z0-9\u00e0-\u00ff \-]/g, '').trim(); const numberPart = (invoiceNumber || '').replace(/[^a-zA-Z0-9\-]/g, '').trim(); const parts = [datePart, supplierPart, numberPart].filter(Boolean); const filename = parts.length > 0 ? `${parts.join(' - ')}.pdf` : fallback; // Passer le filename au serveur pour qu'il soit dans Content-Disposition const downloadUrl = `/api/download-bap?pdfPath=${encodeURIComponent(pdfUrl)}&filename=${encodeURIComponent(filename)}`; const a = document.createElement('a'); a.href = downloadUrl; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); } export default function BapHistory() { const { data: entries, isLoading, refetch } = trpc.bapHistory.getAll.useQuery(); const deleteMutation = trpc.bapHistory.delete.useMutation(); const regenerateMutation = trpc.bapHistory.regenerate.useMutation(); const [search, setSearch] = useState(""); const [regeneratingId, setRegeneratingId] = useState(null); const handleRegenerate = async (id: number) => { setRegeneratingId(id); try { const result = await regenerateMutation.mutateAsync({ id }); toast.success('PDF re-généré avec succès'); refetch(); } catch (err: any) { toast.error(err.message || 'Erreur lors de la re-génération du PDF'); } finally { setRegeneratingId(null); } }; const filtered = (entries || []).filter((e) => { const q = search.toLowerCase(); return ( !q || (e.supplierName || "").toLowerCase().includes(q) || (e.invoiceNumber || "").toLowerCase().includes(q) || (e.serviceConcerne || "").toLowerCase().includes(q) || (e.recipientName || "").toLowerCase().includes(q) || (e.typeAchat || "").toLowerCase().includes(q) ); }); const handleDelete = async (id: number) => { try { await deleteMutation.mutateAsync({ id }); toast.success("Entrée supprimée"); refetch(); } catch { toast.error("Impossible de supprimer cette entrée"); } }; const formatDate = (d: Date | string | null) => { if (!d) return "—"; return new Date(d).toLocaleDateString("fr-FR", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", }); }; const formatAmount = (a: string | null) => { if (!a) return "—"; const n = parseFloat(a); return isNaN(n) ? a : n.toLocaleString("fr-FR", { style: "currency", currency: "EUR" }); }; return (
{/* Header */}

Historique BAP

Toutes les factures validées "Bon à Payer" avec leur PDF annoté

{/* Stats rapides */}
{(entries || []).length}
Total validations
{(entries || []).filter((e) => e.exportMode === "browser").length}
Ouverts navigateur
{(entries || []).filter((e) => e.exportMode === "folder").length}
Exportés dossier
{(entries || []).filter((e) => e.signatureName).length}
Avec signature
{/* Tableau */}
Validations BAP {filtered.length} résultat{filtered.length !== 1 ? "s" : ""} {search ? ` pour "${search}"` : ""}
setSearch(e.target.value)} className="pl-9 h-9" />
{isLoading ? (
Chargement...
) : filtered.length === 0 ? (

{search ? "Aucun résultat pour cette recherche" : "Aucune validation BAP enregistrée"}

) : (
Date validation
N° Facture
Destinataire
Service Signature PDF Actions
{filtered.map((entry) => ( {formatDate(entry.validatedAt)} {entry.invoiceNumber || "—"} {entry.recipientName || ( TOUS )} {entry.serviceConcerne || "—"} {entry.signatureName ? ( {entry.signatureName} ) : ( )} {entry.pdfUrl ? (
) : entry.exportPath ? (
Dossier
{/* Bouton Re-générer si le PDF de dossier n'est plus accessible */}
) : (
)}
{/* Bouton Réexporter (re-télécharger) */} {entry.pdfUrl && ( )} {/* Bouton Re-générer (recréer le PDF annoté depuis la base) */} {/* Bouton Supprimer */}
))}
)}
); }