Spaces:
Build error
Build error
| 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, | |
| }; | |
| }; | |