upload multiple files
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { useParams, useNavigate, Link } from 'react-router-dom';
|
||||
import { getCelebrityById, updateCelebrity, deleteCelebrity, uploadImage, setProfileImage, deleteImage, addImageFromUrl } from '../services/api';
|
||||
import { getCelebrityById, updateCelebrity, deleteCelebrity, uploadImages, setProfileImage, deleteImage, addImageFromUrl } from '../services/api';
|
||||
import EditableField from './EditableField';
|
||||
import './CelebrityProfile.css';
|
||||
|
||||
@@ -14,7 +14,7 @@ function CelebrityProfile() {
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
// Stati per la gestione upload
|
||||
const [selectedFile, setSelectedFile] = useState(null);
|
||||
const [selectedFiles, setSelectedFiles] = useState(null); // Da file a files
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
const [imageUrl, setImageUrl] = useState('');
|
||||
const [isFetchingFromUrl, setIsFetchingFromUrl] = useState(false);
|
||||
@@ -43,12 +43,13 @@ function CelebrityProfile() {
|
||||
}
|
||||
}, [id, navigate, fetchProfile]);
|
||||
|
||||
// Effetto per caricare il file quando `selectedFile` cambia
|
||||
// Effetto per caricare i file quando `selectedFiles` cambia
|
||||
useEffect(() => {
|
||||
if (selectedFile) {
|
||||
if (selectedFiles && selectedFiles.length > 0) {
|
||||
handleUpload();
|
||||
}
|
||||
}, [selectedFile]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedFiles]);
|
||||
|
||||
const handleFieldSave = async (fieldName, newValue) => {
|
||||
let valueToSend = newValue === '' ? null : newValue;
|
||||
@@ -77,22 +78,26 @@ function CelebrityProfile() {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// --- Gestori per le Immagini ---
|
||||
const handleFileChange = (e) => setSelectedFile(e.target.files[0]);
|
||||
const handleFileChange = (e) => {
|
||||
if (e.target.files.length > 0) {
|
||||
setSelectedFiles(Array.from(e.target.files));
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpload = async () => {
|
||||
if (!selectedFile) return;
|
||||
if (!selectedFiles || selectedFiles.length === 0) return;
|
||||
setIsUploading(true);
|
||||
setError(null);
|
||||
try {
|
||||
await uploadImage(id, selectedFile);
|
||||
setSelectedFile(null);
|
||||
document.querySelector('input[type="file"]').value = ""; // Reset del campo file
|
||||
fetchProfile(); // Ricarica i dati per vedere la nuova immagine
|
||||
await uploadImages(id, selectedFiles); // Chiama la nuova funzione plurale
|
||||
fetchProfile();
|
||||
} catch (err) {
|
||||
setError(`Upload fallito: ${err.message}`);
|
||||
} finally {
|
||||
setSelectedFiles(null);
|
||||
if(fileInputRef.current) fileInputRef.current.value = "";
|
||||
setIsUploading(false);
|
||||
}
|
||||
};
|
||||
@@ -142,7 +147,7 @@ function CelebrityProfile() {
|
||||
setIsDraggingOver(false);
|
||||
const files = e.dataTransfer.files;
|
||||
if (files && files.length > 0) {
|
||||
setSelectedFile(files[0]);
|
||||
setSelectedFiles(Array.from(files));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -177,7 +182,7 @@ function CelebrityProfile() {
|
||||
|
||||
<main className="profile-content">
|
||||
{error && <p className="error-message"><strong>Errore:</strong> {error}</p>}
|
||||
|
||||
|
||||
<details open>
|
||||
<summary><h3>Galleria e Upload</h3></summary>
|
||||
<div className="gallery-grid">
|
||||
@@ -207,8 +212,11 @@ function CelebrityProfile() {
|
||||
onDragLeave={handleDragLeave}
|
||||
aria-busy={isUploading}
|
||||
>
|
||||
<input type="file" ref={fileInputRef} onChange={handleFileChange} hidden />
|
||||
{isUploading ? <p>Caricamento...</p> : <p>Trascina un file qui, o <strong>clicca per selezionare</strong>.</p>}
|
||||
<input type="file" ref={fileInputRef} onChange={handleFileChange} hidden multiple />
|
||||
{isUploading
|
||||
? <p>Caricamento di {selectedFiles.length} file...</p>
|
||||
: <p>Trascina i file qui, o <strong>clicca per selezionare</strong>.</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -251,7 +259,7 @@ function CelebrityProfile() {
|
||||
<EditableField label="Corporatura" name="body_type" value={celebrity.body_type} onSave={handleFieldSave} />
|
||||
</div>
|
||||
</details>
|
||||
|
||||
|
||||
<details>
|
||||
<summary><h3>Misure Corporee</h3></summary>
|
||||
<div className="profile-grid">
|
||||
@@ -277,7 +285,7 @@ function CelebrityProfile() {
|
||||
</div>
|
||||
</details>
|
||||
)}
|
||||
|
||||
|
||||
<details>
|
||||
<summary><h3>Biografia</h3></summary>
|
||||
<EditableField label="Note biografiche" name="biography" value={celebrity.biography} type="textarea" onSave={handleFieldSave} />
|
||||
|
||||
@@ -60,6 +60,20 @@ export const uploadImage = async (celebrityId, file) => {
|
||||
return handleResponse(response);
|
||||
};
|
||||
|
||||
export const uploadImages = async (celebrityId, files) => {
|
||||
const formData = new FormData();
|
||||
// Aggiunge ogni file allo stesso campo 'files'. Il backend lo interpreterà come una lista.
|
||||
files.forEach(file => {
|
||||
formData.append('files', file);
|
||||
});
|
||||
|
||||
const response = await fetch(`${API_BASE_URL}/celebrities/${celebrityId}/images`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
return handleResponse(response);
|
||||
};
|
||||
|
||||
export const setProfileImage = async (celebrityId, imageId) => {
|
||||
const response = await fetch(`${API_BASE_URL}/celebrities/${celebrityId}/profile-image`, {
|
||||
method: 'PUT',
|
||||
|
||||
Reference in New Issue
Block a user