initial commit - code moved to separate repo
This commit is contained in:
116
components/FileUploadWithPreview .tsx
Normal file
116
components/FileUploadWithPreview .tsx
Normal file
@ -0,0 +1,116 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import axiosInstance from '../src/axiosSecure'; // Adjust the import path as needed
|
||||
import { CircularProgress } from '@mui/material'; // Import MUI CircularProgress for loading indicator
|
||||
|
||||
const FileUploadWithPreview = ({ name, value, prefix, onUpload, label }) => {
|
||||
// Function to transform the original image URL to its corresponding thumbnail URL
|
||||
function transformToThumbnailUrl(originalUrl) {
|
||||
if (!originalUrl) return null;
|
||||
if (originalUrl.includes("thumb")) return originalUrl; // If the URL already contains 'thumb', return it as-is
|
||||
const parts = originalUrl.split('/');
|
||||
parts.splice(parts.length - 1, 0, 'thumb'); // Insert 'thumb' before the filename
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
// State for the thumbnail URL
|
||||
const [thumbnail, setThumbnail] = useState(value ? transformToThumbnailUrl(value) : null);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [isUploading, setIsUploading] = useState(false); // New state for tracking upload status
|
||||
|
||||
useEffect(() => {
|
||||
setThumbnail(value ? transformToThumbnailUrl(value) : null);
|
||||
}, [value]);
|
||||
|
||||
const handleDragEnter = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsDragging(true);
|
||||
}, []);
|
||||
|
||||
const handleDragLeave = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsDragging(false);
|
||||
}, []);
|
||||
|
||||
const handleDragOver = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}, []);
|
||||
|
||||
const handleDrop = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsDragging(false);
|
||||
const { files: droppedFiles } = e.dataTransfer;
|
||||
processFile(droppedFiles[0]); // Process only the first dropped file
|
||||
}, []);
|
||||
|
||||
const processFile = async (file) => {
|
||||
if (!file) return;
|
||||
|
||||
setIsUploading(true); // Start uploading
|
||||
const formData = new FormData();
|
||||
formData.append('image', file);
|
||||
formData.append('prefix', prefix);
|
||||
setThumbnail("/");
|
||||
|
||||
try {
|
||||
const response = await axiosInstance.post('upload', formData);
|
||||
const uploadedFile = response.data[0];
|
||||
|
||||
// Update state with the new thumbnail URL
|
||||
setThumbnail(uploadedFile.thumbUrl);
|
||||
|
||||
// Invoke callback if provided
|
||||
if (onUpload) {
|
||||
onUpload(name, uploadedFile.originalUrl);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error uploading image:', error);
|
||||
} finally {
|
||||
setIsUploading(false); // End uploading
|
||||
}
|
||||
};
|
||||
|
||||
const handleFilesChange = (e) => {
|
||||
processFile(e.target.files[0]); // Process only the first selected file
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-2 border-dashed border-2 border-gray-200 dark:border-gray-600 rounded-lg">
|
||||
<label htmlFor={`${name}-file-upload`} className="block text-sm font-medium text-gray-700 mb-1">
|
||||
{label || 'Upload Image'}
|
||||
</label>
|
||||
<input id={`${name}-file-upload`} type="file" accept="image/*" onChange={handleFilesChange} className="hidden" />
|
||||
<div className={`flex flex-col items-center justify-center p-4 ${isDragging ? 'bg-gray-100 dark:bg-gray-700' : 'bg-white dark:bg-gray-800'}`}
|
||||
onDragEnter={handleDragEnter}
|
||||
onDragLeave={handleDragLeave}
|
||||
onDragOver={handleDragOver}
|
||||
onDrop={handleDrop}>
|
||||
{isUploading ? (
|
||||
<CircularProgress /> // Show loading indicator while uploading
|
||||
) : (
|
||||
<>
|
||||
<p className="text-gray-600 dark:text-gray-300 text-xs mb-2">Поставете сникма тук, или изберете файл с бутона</p>
|
||||
<button className="btn bg-blue-500 hover:bg-blue-700 text-white font-bold text-xs py-1 px-2 rounded"
|
||||
onClick={(e) => { e.preventDefault(); document.getElementById(`${name}-file-upload`).click(); }}>
|
||||
Избери сникма
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{
|
||||
thumbnail && (
|
||||
<div className="mt-2 flex justify-center">
|
||||
<div className="max-w-xs max-h-64 overflow-hidden rounded-md">
|
||||
<img src={thumbnail} alt="Thumbnail" className="object-contain w-full h-full" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div >
|
||||
);
|
||||
};
|
||||
|
||||
export default FileUploadWithPreview;
|
Reference in New Issue
Block a user