Jelajahi Sumber

previsualisation KO

jeremy 4 bulan lalu
induk
melakukan
0b45a74a44
1 mengubah file dengan 23 tambahan dan 5 penghapusan
  1. 23 5
      frontend/src/pages/InvoiceScanner.jsx

+ 23 - 5
frontend/src/pages/InvoiceScanner.jsx

@@ -45,6 +45,7 @@ export default function InvoiceScanner() {
   const [editInvoice, setEditInvoice] = useState(null)
   const [editForm, setEditForm] = useState({})
   const [previewId, setPreviewId] = useState(null)
+  const [previewUrl, setPreviewUrl] = useState(null)
 
   const loadProperties = () => api.get('/properties').then(r => setProperties(r.data))
   const loadStats = () => api.get('/scan/stats').then(r => setStats(r.data))
@@ -162,6 +163,23 @@ export default function InvoiceScanner() {
     }
   }
 
+  const openPreview = async (id) => {
+    try {
+      const res = await api.get(`/scan/invoices/${id}/preview`, { responseType: 'blob' })
+      const url = URL.createObjectURL(res.data)
+      setPreviewUrl(url)
+      setPreviewId(id)
+    } catch {
+      toast.error('Impossible de charger l\'aperçu')
+    }
+  }
+
+  const closePreview = () => {
+    if (previewUrl) URL.revokeObjectURL(previewUrl)
+    setPreviewUrl(null)
+    setPreviewId(null)
+  }
+
   const years = [...new Set(invoices.map(i => i.year).filter(Boolean))].sort((a, b) => b - a)
   const allYears = years.length > 0 ? years : [new Date().getFullYear()]
 
@@ -280,7 +298,7 @@ export default function InvoiceScanner() {
                   <p className="text-xs text-gray-400 mt-1 truncate" title={inv.file_path}>{inv.file_path.split('/').slice(-2).join('/')}</p>
                 </div>
                 <div className="flex items-center gap-2 shrink-0">
-                  <button onClick={() => setPreviewId(inv.id)} className="text-sm text-gray-500 hover:text-blue-600" title="Prévisualiser">👁️</button>
+                  <button onClick={() => openPreview(inv.id)} className="text-sm text-gray-500 hover:text-blue-600" title="Prévisualiser">👁️</button>
                   {inv.status === 'pending' && (
                     <>
                       <button onClick={() => openEdit(inv)} className="text-sm text-blue-600 hover:text-blue-800" title="Modifier et approuver">✏️</button>
@@ -299,10 +317,10 @@ export default function InvoiceScanner() {
       )}
 
       {/* Preview modal */}
-      {previewId && (
-        <Modal title="Prévisualisation" onClose={() => setPreviewId(null)}>
+      {previewId && previewUrl && (
+        <Modal title="Prévisualisation" onClose={closePreview}>
           <iframe
-            src={`/api/scan/invoices/${previewId}/preview`}
+            src={previewUrl}
             className="w-full h-[70vh] border rounded-lg"
             title="Aperçu facture"
           />
@@ -315,7 +333,7 @@ export default function InvoiceScanner() {
           <div className="space-y-4">
             <div className="bg-gray-50 rounded-lg p-3 text-xs text-gray-500">
               <p className="truncate">📄 {editInvoice.file_path.split('/').slice(-2).join('/')}</p>
-              <button onClick={() => { setPreviewId(editInvoice.id) }} className="text-blue-600 hover:underline mt-1">Prévisualiser le fichier</button>
+              <button onClick={() => { openPreview(editInvoice.id) }} className="text-blue-600 hover:underline mt-1">Prévisualiser le fichier</button>
             </div>
             <div className="grid grid-cols-2 gap-4">
               <div className="col-span-2">