import React, { useEffect, useRef, useState } from 'react'; import { Download, Maximize2, Check, MessageSquare, Star, Heart } from 'lucide-react'; import { useTheme } from '../../../contexts/ThemeContext'; import { AuthenticatedImage } from '../../common'; import { FeedbackIdentityModal } from '../../gallery/FeedbackIdentityModal'; import { feedbackService } from '../../../services/feedback.service'; import type { BaseGalleryLayoutProps } from './BaseGalleryLayout'; import type { Photo } from '../../../types'; interface MasonryPhotoProps { photo: Photo; isSelected: boolean; isSelectionMode: boolean; onClick: (e: React.MouseEvent) => void; onDownload: (e: React.MouseEvent) => void; onToggleSelect: () => void; style?: React.CSSProperties; allowDownloads?: boolean; feedbackEnabled?: boolean; slug?: string; feedbackOptions?: { allowLikes?: boolean; allowComments?: boolean; requireNameEmail?: boolean; }; onQuickComment?: () => void; } const MasonryPhoto: React.FC = ({ photo, isSelected, isSelectionMode, onClick, onDownload, onToggleSelect, style, allowDownloads = true, feedbackEnabled = false, slug, feedbackOptions, onQuickComment }) => { const [imageHeight, setImageHeight] = useState(200); const [showIdentityModal, setShowIdentityModal] = useState(false); const [pendingAction, setPendingAction] = useState(null); const [savedIdentity, setSavedIdentity] = useState<{ name: string; email: string } | null>(null); // Generate random heights for masonry effect useEffect(() => { const heights = [200, 250, 300, 350, 400]; const randomHeight = heights[Math.floor(Math.random() * heights.length)]; setImageHeight(randomHeight); }, [photo.id]); return (
{/* Feedback Indicators */} {feedbackEnabled && ((photo.comment_count ?? 0) > 0 || (photo.average_rating ?? 0) > 0 || (photo.like_count ?? 0) > 0) && (
{(photo.comment_count ?? 0) > 0 && (
{photo.comment_count ?? 0}
)} {(photo.average_rating ?? 0) > 0 && (
{Number(photo.average_rating ?? 0).toFixed(1)}
)} {(photo.like_count ?? 0) > 0 && (
{photo.like_count ?? 0}
)}
)}
{!isSelectionMode && ( <> {allowDownloads && ( )} {feedbackEnabled && feedbackOptions?.allowComments && onQuickComment && ( )} {feedbackEnabled && feedbackOptions?.allowLikes && ( )} )}
{/* Identity Modal */} { setShowIdentityModal(false); setPendingAction(null); }} onSubmit={async (name, email) => { setSavedIdentity({ name, email }); setShowIdentityModal(false); if (pendingAction) { await feedbackService.submitFeedback(slug!, String(pendingAction.photoId), { feedback_type: pendingAction.type, guest_name: name, guest_email: email, }); setPendingAction(null); } }} feedbackType="like" /> {/* Selection Checkbox (visible on hover or when selected) */} {photo.type === 'collage' && (
Collage
)}
); }; export const MasonryGalleryLayout: React.FC = ({ photos, slug, onPhotoClick, onOpenPhotoWithFeedback, onDownload, selectedPhotos = new Set(), isSelectionMode = false, onPhotoSelect, allowDownloads = true, feedbackEnabled = false, feedbackOptions }) => { const { theme } = useTheme(); const containerRef = useRef(null); const [columns, setColumns] = useState(3); const gallerySettings = theme.gallerySettings || {}; const gutter = gallerySettings.masonryGutter || 16; // Calculate number of columns based on container width useEffect(() => { const updateColumns = () => { if (containerRef.current) { const width = containerRef.current.offsetWidth; if (width < 640) setColumns(2); else if (width < 1024) setColumns(3); else if (width < 1280) setColumns(4); else setColumns(5); } }; updateColumns(); window.addEventListener('resize', updateColumns); return () => window.removeEventListener('resize', updateColumns); }, []); // Distribute photos across columns const photoColumns: Photo[][] = Array.from({ length: columns }, () => []); photos.forEach((photo, index) => { photoColumns[index % columns].push(photo); }); return (
{photoColumns.map((column, columnIndex) => (
{column.map((photo) => { const originalIndex = photos.findIndex(p => p.id === photo.id); return ( onPhotoClick(originalIndex)} onDownload={(e) => onDownload(photo, e)} onToggleSelect={() => onPhotoSelect && onPhotoSelect(photo.id)} allowDownloads={allowDownloads} feedbackEnabled={feedbackEnabled} slug={slug} feedbackOptions={feedbackOptions} onQuickComment={() => onOpenPhotoWithFeedback && onOpenPhotoWithFeedback(originalIndex)} /> ); })}
))}
); };