import { useState, useMemo } from 'react' import { PhotoLightbox } from './PhotoLightbox' import { PhotoUpload } from './PhotoUpload' import { Upload, Camera } from 'lucide-react' import Modal from '../shared/Modal' import { getLocaleForLanguage, useTranslation } from '../../i18n' import type { Photo, Place, Day } from '../../types' interface PhotoGalleryProps { photos: Photo[] onUpload: (fd: FormData) => Promise onDelete: (photoId: number) => Promise onUpdate: (photoId: number, data: Partial) => Promise places: Place[] days: Day[] tripId: number } export default function PhotoGallery({ photos, onUpload, onDelete, onUpdate, places, days, tripId }: PhotoGalleryProps) { const { t, language } = useTranslation() const [lightboxIndex, setLightboxIndex] = useState(null) const [showUpload, setShowUpload] = useState(false) const [filterDayId, setFilterDayId] = useState('') const filteredPhotos = useMemo(() => { return photos.filter(photo => { if (filterDayId && String(photo.day_id) !== String(filterDayId)) return false return true }) }, [photos, filterDayId]) const handlePhotoClick = (photo) => { const idx = filteredPhotos.findIndex(p => p.id === photo.id) setLightboxIndex(idx) } const handleDelete = async (photoId) => { await onDelete(photoId) if (lightboxIndex !== null) { const newPhotos = filteredPhotos.filter(p => p.id !== photoId) if (newPhotos.length === 0) { setLightboxIndex(null) } else if (lightboxIndex >= newPhotos.length) { setLightboxIndex(newPhotos.length - 1) } } } return (
{/* Header */}

Fotos

{photos.length} {photos.length !== 1 ? 'Fotos' : 'Foto'}

{filterDayId && ( )}
{/* Gallery Grid */}
{filteredPhotos.length === 0 ? (

{t('photos.noPhotos')}

{t('photos.uploadHint')}

) : (
{filteredPhotos.map(photo => ( handlePhotoClick(photo)} /> ))} {/* Upload tile */}
)}
{/* Lightbox */} {lightboxIndex !== null && ( setLightboxIndex(null)} onUpdate={onUpdate} onDelete={handleDelete} days={days} places={places} tripId={tripId} /> )} {/* Upload Modal */} setShowUpload(false)} title={t('common.upload')} size="lg" > { await onUpload(formData) setShowUpload(false) }} onClose={() => setShowUpload(false)} />
) } interface PhotoThumbnailProps { photo: Photo days: Day[] places: Place[] onClick: () => void } function PhotoThumbnail({ photo, days, places, onClick }: PhotoThumbnailProps) { const day = days?.find(d => d.id === photo.day_id) const place = places?.find(p => p.id === photo.place_id) return (
{photo.caption { (e.target as HTMLImageElement).style.display = 'none' const next = (e.target as HTMLImageElement).nextSibling as HTMLElement; if (next) next.style.display = 'flex' }} /> {/* Fallback */}
🖼️
{/* Hover overlay */}
{photo.caption && (

{photo.caption}

)} {(day || place) && (

{day ? `Tag ${day.day_number}` : ''}{day && place ? ' · ' : ''}{place?.name || ''}

)}
) } function formatDate(dateStr, locale) { if (!dateStr) return '' return new Date(dateStr + 'T00:00:00Z').toLocaleDateString(locale, { day: 'numeric', month: 'short', timeZone: 'UTC' }) }