import React, { useState, useEffect } from 'react'; import { Download, Maximize2, Check, ChevronDown, Calendar, Clock } from 'lucide-react'; import { parseISO } from 'date-fns'; import { useTranslation } from 'react-i18next'; import { useLocalizedDate } from '../../../hooks/useLocalizedDate'; import { useTheme } from '../../../contexts/ThemeContext'; import { AuthenticatedImage } from '../../common'; import type { BaseGalleryLayoutProps } from './BaseGalleryLayout'; import type { Photo } from '../../../types'; import { buildResourceUrl } from '../../../utils/url'; interface HeroGalleryLayoutProps extends BaseGalleryLayoutProps { eventName?: string; eventLogo?: string | null; eventDate?: string; expiresAt?: string; } export const HeroGalleryLayout: React.FC = ({ photos, onPhotoClick, onDownload, selectedPhotos = new Set(), isSelectionMode = false, onPhotoSelect, eventName, eventLogo, eventDate, expiresAt }) => { const { t } = useTranslation(); const { format } = useLocalizedDate(); const { theme } = useTheme(); const [heroPhoto, setHeroPhoto] = useState(null); const [hasInitialized, setHasInitialized] = useState(false); const gallerySettings = theme.gallerySettings || {}; const overlayOpacity = gallerySettings.heroOverlayOpacity || 0.3; // Reset initialization when heroImageId changes useEffect(() => { if (gallerySettings.heroImageId) { setHasInitialized(false); } }, [gallerySettings.heroImageId]); // Select hero photo (admin-selected or first photo only if gallery was empty) useEffect(() => { if (photos.length > 0) { const heroId = gallerySettings.heroImageId; console.log('HeroGalleryLayout - heroImageId:', heroId, 'photos:', photos.length); // If admin has selected a specific hero image, always use it if (heroId) { const adminSelectedHero = photos.find(p => p.id === heroId); console.log('Looking for hero photo with ID:', heroId, 'Found:', adminSelectedHero?.filename); if (adminSelectedHero) { setHeroPhoto(adminSelectedHero); setHasInitialized(true); return; } } // Only auto-select first photo on initial load when gallery was empty // This prevents changing the hero when new photos are uploaded if (!hasInitialized) { setHeroPhoto(photos[0]); setHasInitialized(true); } } }, [photos, gallerySettings.heroImageId, hasInitialized]); if (!heroPhoto) return null; // Show all photos including the hero photo in the grid const remainingPhotos = photos; return (
{/* Hero Section */}
{/* Overlay */}
{/* Hero Content */}
{/* Logo - Show custom logo or fallback to PicPeak logo */}
Event logo
{/* Event Title */} {eventName && (

{eventName}

)} {/* Event Dates */} {(eventDate || expiresAt) && (
{eventDate && ( {format(parseISO(eventDate), 'PP')} )} {expiresAt && ( {t('gallery.expires')} {format(parseISO(expiresAt), 'PP')} )}
)}
{/* Scroll Indicator */}
{/* Grid Section */}
{remainingPhotos.map((photo) => { const actualIndex = photos.findIndex(p => p.id === photo.id); return (
{ if (isSelectionMode && onPhotoSelect) { onPhotoSelect(photo.id); } else { onPhotoClick(actualIndex); } }} >
{!isSelectionMode && ( <> )}
{isSelectionMode && (
{selectedPhotos.has(photo.id) && }
)}
); })}
); };