All files / apps/web/src/frontoffice/components FileDropzone.jsx

0% Statements 0/19
0% Branches 0/22
0% Functions 0/3
0% Lines 0/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97                                                                                                                                                                                                 
import { useState, useCallback } from 'react'
import { useDropzone } from 'react-dropzone'
import { Upload, File, X, Loader2 } from 'lucide-react'
 
export default function FileDropzone({ onFileSelect, accept, maxSize = 100 * 1024 * 1024, disabled = false }) {
  const [uploading, setUploading] = useState(false)
  const [uploadedFile, setUploadedFile] = useState(null)
 
  const onDrop = useCallback(async (acceptedFiles) => {
    const file = acceptedFiles[0]
    console.log('FileDropzone - File selected:', file?.name, file?.size)
    if (file) {
      setUploading(true)
      try {
        await onFileSelect(file)
        setUploadedFile(file)
        console.log('FileDropzone - File uploaded successfully')
      } catch (error) {
        console.error('FileDropzone - Error:', error)
      } finally {
        setUploading(false)
      }
    }
  }, [onFileSelect])
 
  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    accept: accept || {
      'application/pdf': ['.pdf'],
      'image/*': ['.png', '.jpg', '.jpeg', '.tiff'],
      'application/vnd.openxmlformats-officedocument.*': ['.docx', '.xlsx', '.pptx'],
      'text/plain': ['.txt'],
    },
    maxSize,
    disabled: disabled || uploading,
    multiple: false
  })
 
  const handleRemove = () => {
    setUploadedFile(null)
  }
 
  if (uploadedFile && !uploading) {
    return (
      <div className="border-2 border-dashed border-green-300 rounded-lg p-6 bg-green-50">
        <div className="flex items-center justify-center">
          <File className="w-8 h-8 text-green-600 mr-3" />
          <div className="text-left flex-1">
            <div className="font-medium text-gray-900">{uploadedFile.name}</div>
            <div className="text-sm text-gray-500">{(uploadedFile.size / 1024 / 1024).toFixed(2)} MB</div>
          </div>
          <button
            onClick={handleRemove}
            className="p-2 text-gray-400 hover:text-red-600 transition-colors"
          >
            <X className="w-5 h-5" />
          </button>
        </div>
      </div>
    )
  }
 
  return (
    <div
      {...getRootProps()}
      className={`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${
        isDragActive
          ? 'border-purple-500 bg-purple-50'
          : 'border-gray-300 hover:border-purple-400 hover:bg-gray-50'
      } ${disabled || uploading ? 'opacity-50 cursor-not-allowed' : ''}`}
    >
      <input {...getInputProps()} />
      {uploading ? (
        <>
          <Loader2 className="w-10 h-10 text-purple-500 mx-auto mb-3 animate-spin" />
          <p className="text-purple-600">Traitement en cours...</p>
        </>
      ) : isDragActive ? (
        <>
          <Upload className="w-10 h-10 text-purple-500 mx-auto mb-3" />
          <p className="text-lg text-purple-600">Déposez le fichier ici...</p>
        </>
      ) : (
        <>
          <Upload className="w-10 h-10 text-gray-400 mx-auto mb-3" />
          <p className="text-lg text-gray-600 mb-2">
            Glissez-déposez un fichier, ou cliquez pour sélectionner
          </p>
          <p className="text-sm text-gray-500">
            PDF, Images, Office, TXT • Max {(maxSize / 1024 / 1024).toFixed(0)}MB
          </p>
        </>
      )}
    </div>
  )
}