import { useEffect, useState } from 'react'
import api from '../api'
import toast from 'react-hot-toast'
const STATUS_LABELS = {
pending: { label: 'En attente', class: 'bg-yellow-100 text-yellow-800' },
approved: { label: 'Approuvée', class: 'bg-green-100 text-green-800' },
rejected: { label: 'Rejetée', class: 'bg-red-100 text-red-800' },
}
function WideModal({ title, onClose, children }) {
return (
📄 Scanner de factures
Détection automatique et approbation des factures
{propertiesWithScan.length > 0 && (
)}
{/* Stats */}
{stats && (
{stats.pending}
En attente
{stats.approved}
Approuvées
{stats.rejected}
Rejetées
)}
{/* Scan buttons per property */}
{propertiesWithScan.length > 0 && (
Biens avec dossier de scan configuré
{propertiesWithScan.map(p => (
{p.name}
{p.scan_directory}
{p.scan_cron_enabled ? Auto : null}
))}
{scanResult && (
Résultat : {scanResult.scanned} fichier(s) analysé(s), {scanResult.new} nouveau(x), {scanResult.duplicates} doublon(s), {scanResult.errors} erreur(s)
)}
)}
{propertiesWithScan.length === 0 && (
📂
Aucun bien n'a de dossier de scan configuré.
Rendez-vous dans la page Biens pour configurer un dossier de scan.
)}
{/* Filters */}
setFilterText(e.target.value)} placeholder="🔍 Filtrer par nom de fichier..." />
{/* Selection toolbar */}
{selected.size > 0 && (
{selected.size} sélectionnée(s)
)}
{/* Invoice list */}
{filteredInvoices.length === 0 ? (
Aucune facture scannée pour les filtres sélectionnés
) : (
{/* Select all header */}
0}
onChange={toggleSelectAll} className="rounded border-gray-300 text-blue-600" />
Tout sélectionner ({filteredInvoices.length})
{filteredInvoices.map(inv => (
toggleSelect(inv.id)}
className="rounded border-gray-300 text-blue-600 shrink-0 mt-1 sm:mt-0" />
{STATUS_LABELS[inv.status]?.label}
{inv.detected_label || 'Facture à identifier'}
{inv.year && {inv.year}}
🏠 {inv.property_name}
{inv.detected_supplier && 🏢 {inv.detected_supplier}}
{inv.detected_category && 📁 {categories.find(c => c.value === inv.detected_category)?.label || inv.detected_category}}
{inv.detected_amount != null && 💰 {inv.detected_amount.toFixed(2)} €}
{inv.file_path.split('/').slice(-2).join('/')}
{inv.status === 'pending' && (
<>
>
)}
{inv.status !== 'approved' && (
)}
))}
)}
{/* Preview modal */}
{previewId && previewUrl && (
)}
{/* Edit/Approve modal - split layout */}
{editInvoice && (
{/* Left: PDF preview + download */}
{editPreviewUrl ? (
) : (
Chargement de l'aperçu...
)}
📄 {editInvoice.file_path.split('/').slice(-2).join('/')}
{/* Right: form */}
)}
)
}