import React from 'react'; import { Link } from 'react-router-dom'; import { Calendar, Clock, Download, LogOut } from 'lucide-react'; import { parseISO } from 'date-fns'; import { useTranslation } from 'react-i18next'; import { useLocalizedDate } from '../../hooks/useLocalizedDate'; import { Button } from '../common'; import { DynamicFavicon } from '../common/DynamicFavicon'; import { useTheme } from '../../contexts/ThemeContext'; import { buildResourceUrl } from '../../utils/url'; interface GalleryLayoutProps { event: { event_name: string; event_type?: string; event_date?: string; expires_at?: string; }; brandingSettings?: { company_name?: string; company_tagline?: string; support_email?: string; footer_text?: string; favicon_url?: string; logo_url?: string; logo_size?: 'small' | 'medium' | 'large' | 'xlarge' | 'custom'; logo_max_height?: number; logo_position?: 'left' | 'center' | 'right'; logo_display_header?: boolean; logo_display_hero?: boolean; logo_display_mode?: 'logo_only' | 'text_only' | 'logo_and_text'; }; showLogout?: boolean; onLogout?: () => void; showDownloadAll?: boolean; onDownloadAll?: () => void; isDownloading?: boolean; headerExtra?: React.ReactNode; menuButton?: React.ReactNode; children: React.ReactNode; } export const GalleryLayout: React.FC = ({ event, brandingSettings, showLogout = false, onLogout, showDownloadAll = false, onDownloadAll, isDownloading = false, headerExtra, menuButton, children, }) => { const { t } = useTranslation(); const { format } = useLocalizedDate(); const { theme } = useTheme(); const isNonGridLayout = theme.galleryLayout && theme.galleryLayout !== 'grid' && theme.galleryLayout !== 'hero'; const fontFamily = theme.fontFamily || 'Inter, sans-serif'; const headingFontFamily = theme.headingFontFamily || fontFamily; // Calculate logo size classes based on settings const getLogoDimensions = (context: 'header' | 'hero'): { className: string; style?: React.CSSProperties } => { const size = brandingSettings?.logo_size || 'medium'; const maxHeight = brandingSettings?.logo_max_height || 48; if (size === 'custom') { return { className: '', style: { maxHeight: `${maxHeight}px`, height: 'auto' } }; } const sizeMap: Record<'small' | 'medium' | 'large' | 'xlarge', string> = { small: context === 'header' ? 'h-6 sm:h-8' : 'h-12 sm:h-14 lg:h-16', medium: context === 'header' ? 'h-8 sm:h-10 lg:h-12' : 'h-16 sm:h-20 lg:h-24', large: context === 'header' ? 'h-10 sm:h-12 lg:h-16' : 'h-20 sm:h-24 lg:h-32', xlarge: context === 'header' ? 'h-12 sm:h-16 lg:h-20' : 'h-24 sm:h-32 lg:h-40' }; return { className: sizeMap[size as keyof typeof sizeMap] || sizeMap.medium, style: undefined }; }; // Determine logo position classes const getLogoPositionClass = () => { const position = brandingSettings?.logo_position || 'left'; return { left: 'justify-start', center: 'justify-center', right: 'justify-end' }[position]; }; // Check if logo should be displayed const shouldShowLogo = (context: 'header' | 'hero') => { const displayMode = brandingSettings?.logo_display_mode || 'logo_and_text'; if (displayMode === 'text_only') return false; if (context === 'header') { return brandingSettings?.logo_display_header !== false; } else { return brandingSettings?.logo_display_hero !== false; } }; // Check if company name should be displayed const shouldShowCompanyName = () => { const displayMode = brandingSettings?.logo_display_mode || 'logo_and_text'; return displayMode !== 'logo_only'; }; const headerLogoSize = getLogoDimensions('header'); const heroLogoSize = getLogoDimensions('hero'); return (
{/* Dynamic Favicon */} {/* Header structure */}
{/* For non-grid layouts (excluding hero) - keep the current structure */} {isNonGridLayout && (
{/* Left side - Menu button and other header extras */}
{menuButton} {headerExtra}
{/* Right side - Download and Logout */}
{/* Download all button */} {showDownloadAll && onDownloadAll && ( )} {/* Logout button */} {showLogout && onLogout && ( )}
)} {/* For grid layout - everything in one bar */} {!isNonGridLayout && theme.galleryLayout !== 'hero' && (
{/* Left side - Menu button, Logo */}
{/* Menu button */} {menuButton && (
{menuButton}
)} {/* Logo - Show custom logo or fallback to PicPeak logo */} {shouldShowLogo('header') && (
{brandingSettings?.company_name {shouldShowCompanyName() && brandingSettings?.company_name && ( {brandingSettings.company_name} )}
)} {!shouldShowLogo('header') && shouldShowCompanyName() && brandingSettings?.company_name && (
{brandingSettings.company_name || 'PicPeak'}
)}
{/* Center - Event info */}

{event.event_name}

{(event.event_date || event.expires_at) && (
{event.event_date && ( {format(parseISO(event.event_date), 'PP')} )} {event.expires_at && ( {t('gallery.expires')} {format(parseISO(event.expires_at), 'PP')} )}
)}
{/* Right side - Action buttons */}
{/* Extra header items (upload button, etc.) */} {headerExtra && (
{headerExtra}
)} {/* Download all button - hidden on mobile when sidebar is shown */} {showDownloadAll && onDownloadAll && ( )} {/* Logout button */} {showLogout && onLogout && ( )}
{/* Mobile dates row */} {(event.event_date || event.expires_at) && (
{event.event_date && ( {format(parseISO(event.event_date), 'PP')} )} {event.expires_at && ( {t('gallery.expires')} {format(parseISO(event.expires_at), 'PP')} )}
)}
)} {/* For hero layout - minimal header with just menu and logout */} {theme.galleryLayout === 'hero' && (
{/* Left side - Menu button */}
{menuButton} {headerExtra}
{/* Right side - Action buttons */}
{/* Download all button */} {showDownloadAll && onDownloadAll && ( )} {/* Logout button */} {showLogout && onLogout && ( )}
)}
{/* Hero Header for non-grid layouts (excluding hero layout which has its own) */} {isNonGridLayout && (
{/* Logo - Show custom logo or fallback to PicPeak logo */} {shouldShowLogo('hero') && (
{brandingSettings?.company_name {shouldShowCompanyName() && brandingSettings?.company_name && (
{brandingSettings.company_name}
)}
)} {!shouldShowLogo('hero') && shouldShowCompanyName() && brandingSettings?.company_name && (
{brandingSettings.company_name || 'PicPeak'}
)} {/* Event Name */}

{event.event_name}

{/* Event Details */} {(event.event_date || event.expires_at) && (
{event.event_date && ( {format(parseISO(event.event_date), 'PP')} )} {event.expires_at && ( {t('gallery.expires')} {format(parseISO(event.expires_at), 'PP')} )}
)}
{/* Decorative bottom wave */}
)} {/* Main Content */}
{children}
{/* Footer */}
); }; GalleryLayout.displayName = 'GalleryLayout';