import { useState, useCallback } from 'react' import { useDropzone } from 'react-dropzone' import { Upload, X, Image } from 'lucide-react' import { useTranslation } from '../../i18n' import type { Place, Day } from '../../types' interface PhotoUploadProps { tripId: number days: Day[] places: Place[] onUpload: (fd: FormData) => Promise onClose: () => void } export function PhotoUpload({ tripId, days, places, onUpload, onClose }: PhotoUploadProps) { const { t } = useTranslation() const [files, setFiles] = useState([]) const [dayId, setDayId] = useState('') const [placeId, setPlaceId] = useState('') const [caption, setCaption] = useState('') const [uploading, setUploading] = useState(false) const [progress, setProgress] = useState(0) const onDrop = useCallback((acceptedFiles) => { const withPreview = acceptedFiles.map(file => Object.assign(file, { preview: URL.createObjectURL(file) }) ) setFiles(prev => [...prev, ...withPreview]) }, []) const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, accept: { 'image/*': ['.jpeg', '.jpg', '.png', '.gif', '.webp', '.heic'] }, maxFiles: 30, maxSize: 10 * 1024 * 1024, }) const removeFile = (index) => { setFiles(prev => { URL.revokeObjectURL(prev[index].preview) return prev.filter((_, i) => i !== index) }) } const handleUpload = async () => { if (files.length === 0) return setUploading(true) setProgress(0) try { const formData = new FormData() files.forEach(file => formData.append('photos', file)) if (dayId) formData.append('day_id', dayId) if (placeId) formData.append('place_id', placeId) if (caption) formData.append('caption', caption) await onUpload(formData) files.forEach(f => URL.revokeObjectURL(f.preview)) setFiles([]) } catch (err: unknown) { console.error('Upload failed:', err) } finally { setUploading(false) setProgress(0) } } const formatSize = (bytes) => { if (bytes < 1024) return `${bytes} B` if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB` return `${(bytes / 1024 / 1024).toFixed(1)} MB` } return (
{/* Dropzone */}
{isDragActive ? (

Fotos hier ablegen...

) : ( <>

Fotos hier ablegen

{t('photos.clickToSelect')}

JPG, PNG, WebP · max. 10 MB · bis zu 30 Fotos

)}
{/* Preview grid */} {files.length > 0 && (

{files.length} Foto{files.length !== 1 ? 's' : ''} ausgewählt

{files.map((file, idx) => (
{file.name}
{formatSize(file.size)}
))}
)} {/* Options */} {files.length > 0 && (
setCaption(e.target.value)} placeholder="Optionale Beschriftung..." className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-slate-900" />
)} {/* Upload progress */} {uploading && (
Wird hochgeladen...
)} {/* Actions */}
) }