Make gallery page fully mobile responsive

GalleryLayout improvements:
- Stack header elements vertically on mobile
- Hide company branding on small screens
- Make dates stack vertically
- Responsive text sizes and padding
- Icon-only logout button on mobile
- Improved button layout with proper wrapping

PhotoFilterBar improvements:
- Stack search and sort vertically on mobile
- Full-width sort button on mobile
- Horizontally scrollable category filters
- Responsive text sizes
- Mobile-friendly dropdown positioning

PhotoGrid improvements:
- Responsive selection controls
- Touch-friendly photo overlays
- Larger selection checkboxes on mobile
- Improved button text for small screens
- Responsive gaps between photos

Gallery grid CSS:
- Smaller gaps on mobile devices
- Maintains 2 columns on smallest screens

GalleryPage login:
- Responsive padding and margins
- Smaller text and icon sizes on mobile
- Better card spacing
- Responsive form elements

UserPhotoUpload modal:
- Full-screen modal on mobile (slides up from bottom)
- Responsive padding and text sizes
- Mobile-optimized upload area
- Sticky footer on mobile

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-07-09 09:53:24 +02:00
parent f5cf757142
commit d8fb4c9565
7 changed files with 131 additions and 108 deletions
@@ -51,42 +51,42 @@ export const GalleryLayout: React.FC<GalleryLayoutProps> = ({
{/* Header */}
<header className="bg-white border-b border-neutral-200 sticky top-0 z-40">
<div className="container py-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<div className="container py-3 sm:py-4">
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
<div className="flex items-start sm:items-center gap-3 sm:gap-4">
{/* Company logo */}
{brandingSettings?.logo_url && (
<div className="pr-4 border-r border-neutral-200">
<div className="hidden sm:block pr-4 border-r border-neutral-200 flex-shrink-0">
<img
src={`${import.meta.env.VITE_API_URL || 'http://localhost:3001'}${brandingSettings.logo_url}`}
alt={brandingSettings.company_name || 'Company Logo'}
className="h-12 w-auto object-contain"
className="h-10 sm:h-12 w-auto object-contain"
/>
</div>
)}
{/* Company branding */}
{!brandingSettings?.logo_url && brandingSettings?.company_name && (
<div className="pr-4 border-r border-neutral-200">
<h2 className="text-lg font-semibold text-neutral-800">{brandingSettings.company_name}</h2>
<div className="hidden sm:block pr-4 border-r border-neutral-200 flex-shrink-0">
<h2 className="text-base sm:text-lg font-semibold text-neutral-800">{brandingSettings.company_name}</h2>
{brandingSettings.company_tagline && (
<p className="text-xs text-neutral-600">{brandingSettings.company_tagline}</p>
<p className="hidden lg:block text-xs text-neutral-600">{brandingSettings.company_tagline}</p>
)}
</div>
)}
<div>
<h1 className="text-2xl font-bold text-neutral-900">{event.event_name}</h1>
<div className="flex-1">
<h1 className="text-xl sm:text-2xl font-bold text-neutral-900 leading-tight">{event.event_name}</h1>
{(event.event_date || event.expires_at) && (
<div className="flex items-center gap-4 mt-1 text-sm text-neutral-600">
<div className="flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-4 mt-1 text-xs sm:text-sm text-neutral-600">
{event.event_date && (
<span className="flex items-center">
<Calendar className="w-4 h-4 mr-1" />
{format(parseISO(event.event_date), 'PP')}
<Calendar className="w-3 h-3 sm:w-4 sm:h-4 mr-1" />
<span className="truncate">{format(parseISO(event.event_date), 'PP')}</span>
</span>
)}
{event.expires_at && (
<span className="flex items-center">
<Clock className="w-4 h-4 mr-1" />
{t('gallery.expires')} {format(parseISO(event.expires_at), 'PP')}
<Clock className="w-3 h-3 sm:w-4 sm:h-4 mr-1" />
<span className="truncate">{t('gallery.expires')} {format(parseISO(event.expires_at), 'PP')}</span>
</span>
)}
</div>
@@ -94,7 +94,7 @@ export const GalleryLayout: React.FC<GalleryLayoutProps> = ({
</div>
</div>
<div className="flex items-center gap-2">
<div className="flex items-center gap-2 flex-wrap sm:flex-nowrap">
{headerExtra}
{showDownloadAll && onDownloadAll && (
<Button
@@ -103,8 +103,10 @@ export const GalleryLayout: React.FC<GalleryLayoutProps> = ({
leftIcon={<Download className="w-4 h-4" />}
onClick={onDownloadAll}
isLoading={isDownloading}
className="flex-1 sm:flex-initial text-sm sm:text-base"
>
{t('gallery.downloadAll')}
<span className="hidden sm:inline">{t('gallery.downloadAll')}</span>
<span className="sm:hidden">{t('common.downloadAll')}</span>
</Button>
)}
{showLogout && onLogout && (
@@ -113,8 +115,10 @@ export const GalleryLayout: React.FC<GalleryLayoutProps> = ({
size="md"
leftIcon={<LogOut className="w-4 h-4" />}
onClick={onLogout}
className="text-sm sm:text-base"
>
{t('common.logout')}
<span className="hidden sm:inline">{t('common.logout')}</span>
<span className="sm:hidden"><LogOut className="w-4 h-4" /></span>
</Button>
)}
</div>
@@ -126,20 +130,20 @@ export const GalleryLayout: React.FC<GalleryLayoutProps> = ({
<main className="container">{children}</main>
{/* Footer */}
<footer className="mt-12 py-8 border-t border-neutral-200">
<div className="container text-center">
<footer className="mt-8 sm:mt-12 py-6 sm:py-8 border-t border-neutral-200">
<div className="container text-center px-4">
{brandingSettings?.support_email && (
<p className="text-sm text-neutral-600 mb-2">
<p className="text-xs sm:text-sm text-neutral-600 mb-2">
{t('gallery.needHelp')}{' '}
<a
href={`mailto:${brandingSettings.support_email}`}
className="text-primary-600 hover:text-primary-700"
className="text-primary-600 hover:text-primary-700 break-all"
>
{brandingSettings.support_email}
</a>
</p>
)}
<p className="text-sm text-neutral-500">
<p className="text-xs sm:text-sm text-neutral-500">
{brandingSettings?.footer_text || '© 2024 Your Company. All rights reserved.'}
</p>
{brandingSettings?.company_name && brandingSettings?.company_tagline && (