import React, { useState } from 'react'; import { Check, Download, Trash2, Eye, Package, MessageSquare, Star } from 'lucide-react'; import { toast } from 'react-toastify'; import { AdminPhoto } from '../../services/photos.service'; import { photosService } from '../../services/photos.service'; import { Button } from '../common'; import { AdminAuthenticatedImage } from './AdminAuthenticatedImage'; interface AdminPhotoGridProps { photos: AdminPhoto[]; eventId: number; onPhotoClick: (photo: AdminPhoto, index: number) => void; onPhotosDeleted: () => void; } export const AdminPhotoGrid: React.FC = ({ photos, eventId, onPhotoClick, onPhotosDeleted }) => { const [selectedPhotos, setSelectedPhotos] = useState>(new Set()); const [isSelectionMode, setIsSelectionMode] = useState(false); const [isDeleting, setIsDeleting] = useState(false); const [deletingPhotos, setDeletingPhotos] = useState>(new Set()); const handlePhotoSelect = (photoId: number, e?: React.MouseEvent) => { if (e) { e.stopPropagation(); } // Auto-enable selection mode when selecting via checkbox if (!isSelectionMode) { setIsSelectionMode(true); } const newSelected = new Set(selectedPhotos); if (newSelected.has(photoId)) { newSelected.delete(photoId); } else { newSelected.add(photoId); } setSelectedPhotos(newSelected); }; const handleSelectAll = () => { if (selectedPhotos.size === photos.length) { setSelectedPhotos(new Set()); } else { setSelectedPhotos(new Set(photos.map(p => p.id))); } }; const handleDeleteSingle = async (photo: AdminPhoto, e: React.MouseEvent) => { e.stopPropagation(); if (!confirm(`Are you sure you want to delete "${photo.filename}"?`)) { return; } setDeletingPhotos(prev => new Set(prev).add(photo.id)); try { await photosService.deletePhoto(eventId, photo.id); toast.success('Photo deleted successfully'); onPhotosDeleted(); } catch (error) { toast.error('Failed to delete photo'); setDeletingPhotos(prev => { const newSet = new Set(prev); newSet.delete(photo.id); return newSet; }); } }; const handleDeleteSelected = async () => { if (selectedPhotos.size === 0) return; const count = selectedPhotos.size; if (!confirm(`Are you sure you want to delete ${count} photo${count > 1 ? 's' : ''}?`)) { return; } setIsDeleting(true); const selectedIds = Array.from(selectedPhotos); setDeletingPhotos(new Set(selectedIds)); try { await photosService.deletePhotos(eventId, selectedIds); toast.success(`${count} photo${count > 1 ? 's' : ''} deleted successfully`); setSelectedPhotos(new Set()); setIsSelectionMode(false); onPhotosDeleted(); } catch (error) { toast.error('Failed to delete photos'); setDeletingPhotos(new Set()); } finally { setIsDeleting(false); } }; const handleDownload = async (photo: AdminPhoto, e: React.MouseEvent) => { e.stopPropagation(); try { await photosService.downloadPhoto(eventId, photo.id, photo.filename); toast.success('Download started'); } catch (error) { toast.error('Failed to download photo'); } }; const toggleSelectionMode = () => { setIsSelectionMode(!isSelectionMode); if (isSelectionMode) { setSelectedPhotos(new Set()); } }; return (
{/* Action Bar */}
{(isSelectionMode || selectedPhotos.size > 0) && ( <> {selectedPhotos.size > 0 && ( <> {selectedPhotos.size} selected )} )}
{photos.length} photo{photos.length !== 1 ? 's' : ''}
{/* Photo Grid */}
{photos.map((photo, index) => { const isDeleting = deletingPhotos.has(photo.id); return (
!isDeleting && onPhotoClick(photo, index)} > {/* Selection Checkbox (top-right) */} {/* Thumbnail */}
{photo.thumbnail_url ? (
} /> ) : (
)}
{/* Overlay with actions */}

{photo.filename}

{photosService.formatBytes(photo.size)}

{!isSelectionMode && (
)}
{/* Category Badge - move to top-left and prevent overlap with select checkbox */} {photo.category_name && (
{photo.category_name}
)} {/* Feedback Indicators (moved to bottom-right to avoid covering category) */} {(photo.comment_count > 0 || photo.average_rating > 0 || photo.like_count > 0) && (
{photo.average_rating > 0 && (
{Number(photo.average_rating).toFixed(1)}
)} {photo.comment_count > 0 && (
{photo.comment_count}
)}
)}
); })}
{photos.length === 0 && (

No photos uploaded yet

)} ); };