demo / frontend /src /components /Benchmark /hooks /useDocumentSelection.js
tfrere's picture
minor design fixes | update upload url api calls
f8362f3
raw
history blame
8.2 kB
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,
};
};