From e179def3cceefe5fd6acd5574f2986e4f9e223ef Mon Sep 17 00:00:00 2001 From: Paul Nothaft Date: Fri, 6 Feb 2026 18:03:47 +0100 Subject: [PATCH] feat: add Gallery Premium and Gallery Story layouts (Beta) - Add Gallery Premium layout: elegant light theme with masonry grid, hero section, sticky navigation, and integrated lightbox - Add Gallery Story layout: cinematic dark theme with scene-based sections, carousels, and gold accents - Implement full-page layout support: bypass standard header/footer/ sidebar for immersive experience - Add logout button to both layouts for authenticated galleries - Mark both layouts as (Beta) in theme editor and layout selectors - Fix hero title color visibility in Gallery Premium layout --- .../admin/ThemeCustomizerEnhanced.tsx | 321 +++++--- .../src/components/admin/ThemeEditorModal.tsx | 13 +- .../src/components/gallery/GalleryView.tsx | 80 +- .../gallery/PhotoGridWithLayouts.tsx | 33 +- .../gallery/layouts/BaseGalleryLayout.tsx | 2 + .../gallery/layouts/GalleryPremiumLayout.css | 410 ++++++++++ .../gallery/layouts/GalleryPremiumLayout.tsx | 538 +++++++++++++ .../gallery/layouts/GalleryStoryLayout.css | 743 ++++++++++++++++++ .../gallery/layouts/GalleryStoryLayout.tsx | 376 +++++++++ .../src/components/gallery/layouts/index.ts | 2 + .../gallery/layouts/story/StoryCarousel.tsx | 66 ++ .../layouts/story/StoryFeedbackSheet.tsx | 172 ++++ .../gallery/layouts/story/StoryHero.tsx | 93 +++ .../gallery/layouts/story/StoryPhotoCard.tsx | 104 +++ .../gallery/layouts/story/StoryScene.tsx | 45 ++ .../layouts/story/StoryScrollToTop.tsx | 45 ++ .../components/gallery/layouts/story/index.ts | 6 + frontend/src/i18n/locales/de.json | 72 +- frontend/src/i18n/locales/en.json | 72 +- frontend/src/types/theme.types.ts | 155 +++- 20 files changed, 3227 insertions(+), 121 deletions(-) create mode 100644 frontend/src/components/gallery/layouts/GalleryPremiumLayout.css create mode 100644 frontend/src/components/gallery/layouts/GalleryPremiumLayout.tsx create mode 100644 frontend/src/components/gallery/layouts/GalleryStoryLayout.css create mode 100644 frontend/src/components/gallery/layouts/GalleryStoryLayout.tsx create mode 100644 frontend/src/components/gallery/layouts/story/StoryCarousel.tsx create mode 100644 frontend/src/components/gallery/layouts/story/StoryFeedbackSheet.tsx create mode 100644 frontend/src/components/gallery/layouts/story/StoryHero.tsx create mode 100644 frontend/src/components/gallery/layouts/story/StoryPhotoCard.tsx create mode 100644 frontend/src/components/gallery/layouts/story/StoryScene.tsx create mode 100644 frontend/src/components/gallery/layouts/story/StoryScrollToTop.tsx create mode 100644 frontend/src/components/gallery/layouts/story/index.ts diff --git a/frontend/src/components/admin/ThemeCustomizerEnhanced.tsx b/frontend/src/components/admin/ThemeCustomizerEnhanced.tsx index 29d49837..37d90279 100644 --- a/frontend/src/components/admin/ThemeCustomizerEnhanced.tsx +++ b/frontend/src/components/admin/ThemeCustomizerEnhanced.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { Palette, RotateCcw, Check, Layout, Type, Sparkles, Grid3X3, Layers, Play, Clock, Image, LayoutGrid, ChevronDown, Code, Info, FileCode, ImageIcon, Minimize2, EyeOff } from 'lucide-react'; +import { Palette, RotateCcw, Check, Layout, Type, Sparkles, Grid3X3, Layers, Play, Clock, Image, LayoutGrid, ChevronDown, Code, Info, FileCode, ImageIcon, Minimize2, EyeOff, Menu, SlidersHorizontal, Columns, Film } from 'lucide-react'; import { Button, Card, Input } from '../common'; import { ThemeConfig, GALLERY_THEME_PRESETS, GalleryLayoutType, HeaderStyleType, HeroDividerStyle } from '../../types/theme.types'; import type { EnabledTemplate } from '../../services/cssTemplates.service'; @@ -28,7 +28,9 @@ const layoutIcons: Record = { masonry: , carousel: , timeline: , - mosaic: + mosaic: , + 'gallery-premium': , + 'gallery-story': }; const headerStyleIcons: Record = { @@ -178,7 +180,7 @@ export const ThemeCustomizerEnhanced: React.FC = (
{/* Preset Themes */} -

+

{t('branding.themePresets')}

@@ -189,15 +191,15 @@ export const ThemeCustomizerEnhanced: React.FC = ( onClick={() => handlePresetSelect(key)} className={`relative p-4 rounded-lg border-2 transition-all text-left ${ selectedPreset === key - ? 'border-primary-600 bg-primary-50' - : 'border-neutral-200 hover:border-neutral-300' + ? 'border-primary-600 bg-primary-50 dark:bg-primary-900/30' + : 'border-neutral-200 dark:border-neutral-700 hover:border-neutral-300 dark:hover:border-neutral-600' }`} >
- {theme.name} + {theme.name} {theme.description && ( - {theme.description} + {theme.description} )}
{selectedPreset === key && ( @@ -207,15 +209,15 @@ export const ThemeCustomizerEnhanced: React.FC = (
@@ -233,7 +235,7 @@ export const ThemeCustomizerEnhanced: React.FC = ( {/* Gallery Layout */} {showGalleryLayouts && ( -

+

{t('branding.galleryLayout')}

@@ -244,16 +246,21 @@ export const ThemeCustomizerEnhanced: React.FC = ( onClick={() => handleChange('galleryLayout', layout)} className={`relative p-4 rounded-lg border-2 transition-all ${ localTheme.galleryLayout === layout - ? 'border-primary-600 bg-primary-50' - : 'border-neutral-200 hover:border-neutral-300' + ? 'border-primary-600 bg-primary-50 dark:bg-primary-900/30' + : 'border-neutral-200 dark:border-neutral-700 hover:border-neutral-300 dark:hover:border-neutral-600' }`} >
-
+
{layoutIcons[layout]}
- {layout} - + + {layout} + {(layout === 'gallery-premium' || layout === 'gallery-story') && ( + (Beta) + )} + + {t(`branding.layoutDescriptions.${layout}`)}
@@ -266,19 +273,19 @@ export const ThemeCustomizerEnhanced: React.FC = ( {/* Layout-specific settings */} {localTheme.galleryLayout && ( -
-

{t('branding.layoutSettings')}

+
+

{t('branding.layoutSettings')}

{/* Common settings */}
-