import { useState, useEffect } from 'react'; import { Camera, Upload, LogIn, Settings, ArrowUpDown } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Card, CardContent } from '@/components/ui/card'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { useAuth } from '@/hooks/useAuth'; import { useNavigate } from 'react-router-dom'; import { UppyPhotoSubmissionUpload } from '@/components/upload/UppyPhotoSubmissionUpload'; import { PhotoManagementDialog } from '@/components/upload/PhotoManagementDialog'; import { PhotoModal } from '@/components/moderation/PhotoModal'; import { supabase } from '@/lib/supabaseClient'; import { EntityPhotoGalleryProps } from '@/types/submissions'; import { useUserRole } from '@/hooks/useUserRole'; import { getErrorMessage } from '@/lib/errorHandler'; interface Photo { id: string; url: string; caption?: string; title?: string; user_id: string; created_at: string; } export function EntityPhotoGallery({ entityId, entityType, entityName, parentId }: EntityPhotoGalleryProps) { const { user } = useAuth(); const navigate = useNavigate(); const { isModerator } = useUserRole(); const [photos, setPhotos] = useState([]); const [showUpload, setShowUpload] = useState(false); const [showManagement, setShowManagement] = useState(false); const [loading, setLoading] = useState(true); const [selectedPhotoIndex, setSelectedPhotoIndex] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [sortBy, setSortBy] = useState<'newest' | 'oldest'>('newest'); useEffect(() => { fetchPhotos(); }, [entityId, entityType, sortBy]); const fetchPhotos = async () => { try { // Fetch photos directly from the photos table const { data: photoData, error } = await supabase .from('photos') .select('id, cloudflare_image_url, title, caption, submitted_by, created_at, order_index') .eq('entity_type', entityType) .eq('entity_id', entityId) .order('created_at', { ascending: sortBy === 'oldest' }); if (error) throw error; // Map to Photo interface const mappedPhotos: Photo[] = photoData?.map((photo) => ({ id: photo.id, url: photo.cloudflare_image_url, caption: photo.caption || undefined, title: photo.title || undefined, user_id: photo.submitted_by || '', created_at: photo.created_at, })) || []; setPhotos(mappedPhotos); } catch (error: unknown) { // Photo fetch failed - display empty gallery } finally { setLoading(false); } }; const handleUploadClick = () => { if (!user) { navigate('/auth'); return; } setShowUpload(true); }; const handleSubmissionComplete = () => { setShowUpload(false); fetchPhotos(); // Refresh photos after submission }; const handlePhotoClick = (index: number) => { setSelectedPhotoIndex(index); setIsModalOpen(true); }; const handleCloseModal = () => { setIsModalOpen(false); setSelectedPhotoIndex(null); }; if (showUpload) { return (

Submit Additional Photos for {entityName}

Photos submitted here go through a separate review process

); } if (loading) { return (
Loading photos...
); } return (
{/* Header with Upload and Management Buttons */}

Photo Gallery

Share your photos of {entityName}

{isModerator() && photos.length > 0 && ( )}
{/* Sort Dropdown */} {photos.length > 0 && (
)}
{/* Photo Management Dialog */} {/* Photo Grid */} {photos.length > 0 ? (
{photos.map((photo, index) => ( {photo.title handlePhotoClick(index)} /> {photo.caption && (

{photo.caption}

)}
))}
) : (

No Photos Yet

Be the first to share photos of {entityName}!

)} {/* Photo Lightbox Modal */} {selectedPhotoIndex !== null && ( ({ id: photo.id, url: photo.url, caption: photo.caption, filename: photo.title, }))} initialIndex={selectedPhotoIndex} isOpen={isModalOpen} onClose={handleCloseModal} /> )}
); }