import { useState, useRef } from "react"; import { API_CONFIG, apiService } from "../../../config/api"; /** * Hook personnalisé pour gérer la sélection et l'upload de documents * @returns {Object} - Méthodes et états pour la gestion des documents */ export const useDocumentSelection = (onStartGeneration) => { const [isDragging, setIsDragging] = useState(false); const [uploadStatus, setUploadStatus] = useState(null); const [isLoading, setIsLoading] = useState(false); const [sessionId, setSessionId] = useState(null); const [selectedDocument, setSelectedDocument] = useState(null); const [isDefaultDocument, setIsDefaultDocument] = useState(false); const [urlInput, setUrlInput] = useState(""); const [urlSelected, setUrlSelected] = useState(false); const fileInputRef = useRef(null); const handleDragOver = (e) => { e.preventDefault(); setIsDragging(true); }; const handleDragLeave = () => { setIsDragging(false); }; const handleClick = () => { // Lors d'un clic sur la zone de fichier, seulement ouvrir le dialogue de sélection // mais ne pas réinitialiser les autres options avant que l'utilisateur ne sélectionne réellement un fichier fileInputRef.current.click(); }; const handleFileChange = (e) => { const file = e.target.files[0]; if (!file) return; // Maintenant que l'utilisateur a choisi un fichier, réinitialiser les autres options setUrlInput(""); setUrlSelected(false); setIsDefaultDocument(false); setSessionId(null); // Reset session ID until upload completes // Check if it's a PDF, TXT, HTML or MD if ( !file.name.endsWith(".pdf") && !file.name.endsWith(".txt") && !file.name.endsWith(".html") && !file.name.endsWith(".md") ) { setUploadStatus({ success: false, message: "Only PDF, TXT, HTML and MD files are accepted", }); return { success: false, error: "Invalid file format" }; } // Check file size limit (3MB = 3145728 bytes) if (file.size > 1048576 * 2) { setUploadStatus({ success: false, message: "File size exceeds the 2MB limit", }); return { success: false, error: "File too large" }; } handleFileUpload(file); return { success: true }; }; const handleFileUpload = async (file) => { setIsLoading(true); setUploadStatus(null); // Réinitialiser les sélections précédentes setSelectedDocument(null); try { const result = await apiService.uploadFile(file); setUploadStatus({ success: true, message: "File uploaded successfully", }); setSessionId(result.session_id); setSelectedDocument({ name: file.name }); // Fichier uploadé avec succès, donc on désactive les autres options setIsDefaultDocument(false); setUrlSelected(false); return { success: true }; } catch (error) { setUploadStatus({ success: false, message: error.message || "Server connection error", }); return { success: false, error: error.message || "Server connection error", }; } finally { setIsLoading(false); } }; const handleDrop = async (e) => { e.preventDefault(); setIsDragging(false); // Réinitialiser les autres options setUrlInput(""); setUrlSelected(false); setIsDefaultDocument(false); fileInputRef.current.value = ""; setSessionId(null); // Reset session ID until upload completes const file = e.dataTransfer.files[0]; if (!file) { setUploadStatus({ success: false, message: "No file detected", }); return { success: false, error: "No file detected" }; } // Check if it's a PDF, TXT, HTML or MD if ( !file.name.endsWith(".pdf") && !file.name.endsWith(".txt") && !file.name.endsWith(".html") && !file.name.endsWith(".md") ) { setUploadStatus({ success: false, message: "Only PDF, TXT, HTML and MD files are accepted", }); return { success: false, error: "Invalid file format" }; } // Check file size limit (3MB = 3145728 bytes) if (file.size > 1048576 * 3) { setUploadStatus({ success: false, message: "File size exceeds the 3MB limit", }); return { success: false, error: "File too large" }; } handleFileUpload(file); return { success: true }; }; const handleDefaultDocClick = (doc) => { // Réinitialiser les autres options setUrlInput(""); setUrlSelected(false); fileInputRef.current.value = ""; // Set the selected document setSelectedDocument(doc); if (doc) { setSessionId(doc.id); setIsDefaultDocument(true); } else { // Si on désélectionne setIsDefaultDocument(false); setSessionId(null); } }; const handleGenerateClick = () => { if (onStartGeneration && sessionId) { onStartGeneration(sessionId, isDefaultDocument); } else if (!sessionId) { setUploadStatus({ success: false, message: "Please select or upload a document first", }); } }; const handleUrlInputChange = async (e) => { const url = e.target.value; setUrlInput(url); // Ne pas réinitialiser les autres options tant que l'URL n'est pas valide // Vérification simple d'URL valide avec regex const urlRegex = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/; if (url && urlRegex.test(url)) { // URL valide, maintenant réinitialiser les autres options setIsDefaultDocument(false); fileInputRef.current.value = ""; setUrlSelected(true); // Si l'URL semble valide et a une longueur suffisante, on la traite if (url.length > 10) { await handleUrlUpload(url); } } else if (url && url.length > 5) { // Si l'URL n'est pas valide mais que l'utilisateur a saisi quelque chose setUrlSelected(false); setUploadStatus({ success: false, message: "Please enter a valid URL", }); } else { // Si le champ est vide ou presque vide, réinitialiser complètement setUrlSelected(false); // Si on avait déjà une URL sélectionnée avant et qu'on vide le champ // il faut aussi réinitialiser le document sélectionné et la session if (urlSelected) { setSelectedDocument(null); setSessionId(null); } } }; const handleUrlUpload = async (url) => { setIsLoading(true); setUploadStatus(null); // Réinitialiser les sélections précédentes setSelectedDocument(null); setIsDefaultDocument(false); try { const result = await apiService.uploadUrl(url); setUploadStatus({ success: true, message: "Content from URL uploaded successfully", }); setSessionId(result.session_id); // Extraire le domaine racine de l'URL let domain = url; try { // Utiliser URL API pour extraire le hostname const urlObj = new URL(url.startsWith("http") ? url : `https://${url}`); domain = urlObj.hostname; } catch (e) { console.error("Error parsing URL:", e); } setSelectedDocument({ name: "URL Content", domain: domain, source_url: result.source_url || url, }); return { success: true }; } catch (error) { setUploadStatus({ success: false, message: error.message || "Error processing URL", }); return { success: false, error: error.message || "Error processing URL" }; } finally { setIsLoading(false); } }; return { // États isDragging, isLoading, sessionId, selectedDocument, isDefaultDocument, urlInput, urlSelected, uploadStatus, fileInputRef, // Gestionnaires d'événements handleDragOver, handleDragLeave, handleClick, handleFileChange, handleDrop, handleDefaultDocClick, handleGenerateClick, handleUrlInputChange, // Setters pour les mises à jour externes setUploadStatus, }; };