import { useEffect, useRef, useState } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { useToast } from "@/hooks/use-toast"; import { Clock, FileUp, Send } from "lucide-react"; // URL utilisée quand aucun webhook BAP n'est configuré dans les paramètres const DEFAULT_BAP_WEBHOOK_URL = "https://workflow.ffnancy.fr/webhook/a3d03176-b72f-412d-8fb9-f920b9fbab4d"; interface BapUploadModalProps { open: boolean; onOpenChange: (open: boolean) => void; } // Envoi d'un bon à payer (PDF) au workflow configuré, avec fenêtre d'attente export default function BapUploadModal({ open, onOpenChange }: BapUploadModalProps) { const [selectedFile, setSelectedFile] = useState(null); const [selectedRecipient, setSelectedRecipient] = useState(''); const [isUploading, setIsUploading] = useState(false); const [showWaitingModal, setShowWaitingModal] = useState(false); const [processingSeconds, setProcessingSeconds] = useState(0); const timerRef = useRef | null>(null); const fileInputRef = useRef(null); const { toast } = useToast(); const stopProcessingTimer = () => { if (timerRef.current) { clearInterval(timerRef.current); timerRef.current = null; } }; useEffect(() => stopProcessingTimer, []); const handleFileChange = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (file && file.type === 'application/pdf') { setSelectedFile(file); } else { toast({ title: "Erreur", description: "Veuillez sélectionner un fichier PDF", variant: "destructive", }); } }; const startProcessingTimer = () => { stopProcessingTimer(); setProcessingSeconds(0); timerRef.current = setInterval(() => { setProcessingSeconds(prev => { if (prev >= 60) { stopProcessingTimer(); return 60; } return prev + 1; }); }, 1000); }; const handleCloseWaitingModal = () => { setShowWaitingModal(false); setProcessingSeconds(0); stopProcessingTimer(); }; const clearSelectedFile = () => { setSelectedFile(null); if (fileInputRef.current) fileInputRef.current.value = ''; }; const handleSendBap = async () => { if (!selectedFile || !selectedRecipient) { toast({ title: "Erreur", description: "Veuillez sélectionner un fichier PDF et un destinataire", variant: "destructive", }); return; } // Récupérer l'URL webhook configurée let webhookUrl = ''; try { const configResponse = await fetch('/api/webhook-bap-config', { credentials: 'include' }); if (configResponse.ok) { const config = await configResponse.json(); webhookUrl = config?.webhookUrl; } } catch (error) { console.warn('Impossible de récupérer la config webhook, utilisation URL par défaut'); } if (!webhookUrl) { webhookUrl = DEFAULT_BAP_WEBHOOK_URL; } // Fermer la fenêtre de sélection et ouvrir celle d'attente onOpenChange(false); setShowWaitingModal(true); setIsUploading(true); startProcessingTimer(); try { const formData = new FormData(); formData.append('file', selectedFile); formData.append('recipient', selectedRecipient); formData.append('type', 'BAP'); formData.append('fileName', selectedFile.name); const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 60000); // 60 secondes const response = await fetch(webhookUrl, { method: 'POST', body: formData, signal: controller.signal, }); clearTimeout(timeoutId); if (!response.ok) { throw new Error(`Erreur ${response.status}: ${response.statusText}`); } handleCloseWaitingModal(); toast({ title: "Succès", description: "Fichier BAP envoyé avec succès", }); clearSelectedFile(); setSelectedRecipient(''); } catch (error: any) { handleCloseWaitingModal(); let errorMessage = "Impossible d'envoyer le fichier BAP"; if (error.name === 'AbortError') { errorMessage = "Le traitement a pris trop de temps (timeout de 60 secondes)"; } else if (error.message) { errorMessage = error.message; } toast({ title: "Erreur", description: errorMessage, variant: "destructive", }); // Réouvrir la fenêtre de sélection en cas d'erreur onOpenChange(true); } finally { setIsUploading(false); } }; return ( <> Envoyer un bon à payer (BAP)
{!selectedFile ? ( ) : (

{selectedFile.name}

{(selectedFile.size / 1024 / 1024).toFixed(2)} Mo • PDF

)}
{/* Fenêtre d'attente pendant l'envoi */} { }}> Traitement en cours...
Envoi du fichier vers le workflow...
{processingSeconds < 60 ? `${processingSeconds}s écoulées` : '60s+ écoulées' }
); }