feat: decouple hero header from gallery layouts (#158)

- Add separate header_style setting (hero/standard/minimal/none) that can
  be combined with any layout type (grid/masonry/carousel/timeline/mosaic)
- Create HeroHeader and HeroDivider components for reusable hero section
- Add hero_divider_style setting (wave/straight/angle/curve/none)
- Add database migration for header_style and hero_divider_style columns
- Remove deprecated HeroGalleryLayout component
- Fix various TypeScript errors across the codebase:
  - Add missing type properties (css_template_id, updatedAt, justified settings)
  - Fix null handling for event_date and expires_at fields
  - Fix translation function calls and i18n config
  - Remove unused imports and variables
This commit is contained in:
Paul Nothaft
2026-02-01 22:44:28 +01:00
parent 397d33a95a
commit 7b8d8bd92b
35 changed files with 907 additions and 533 deletions
+15
View File
@@ -45,6 +45,12 @@ export interface Event {
hero_logo_visible?: boolean;
hero_logo_size?: 'small' | 'medium' | 'large' | 'xlarge';
hero_logo_position?: 'top' | 'center' | 'bottom';
hero_logo_url?: string | null;
// Header style settings (decoupled from layout)
header_style?: 'hero' | 'standard' | 'minimal' | 'none';
hero_divider_style?: 'wave' | 'straight' | 'angle' | 'curve' | 'none';
// CSS Template
css_template_id?: number | null;
}
export interface GalleryInfo {
@@ -119,6 +125,14 @@ export interface GalleryData {
enable_devtools_protection?: boolean;
fragmentation_level?: number;
overlay_protection?: boolean;
// Hero logo customization fields
hero_logo_visible?: boolean;
hero_logo_size?: 'small' | 'medium' | 'large' | 'xlarge';
hero_logo_position?: 'top' | 'center' | 'bottom';
hero_logo_url?: string | null;
// Header style settings (decoupled from layout)
header_style?: 'hero' | 'standard' | 'minimal' | 'none';
hero_divider_style?: 'wave' | 'straight' | 'angle' | 'curve' | 'none';
};
categories?: PhotoCategory[];
photos: Photo[];
@@ -159,6 +173,7 @@ export interface AdminUser {
lastLogin?: string | null;
lastLoginIp?: string | null;
createdAt?: string;
updatedAt?: string;
createdByUsername?: string;
}
+27 -9
View File
@@ -1,5 +1,11 @@
// Gallery Layout Types
export type GalleryLayoutType = 'grid' | 'masonry' | 'carousel' | 'timeline' | 'hero' | 'mosaic';
export type GalleryLayoutType = 'grid' | 'masonry' | 'carousel' | 'timeline' | 'mosaic';
// Header Style Types (decoupled from layout)
export type HeaderStyleType = 'hero' | 'standard' | 'minimal' | 'none';
// Hero Divider Styles
export type HeroDividerStyle = 'wave' | 'straight' | 'angle' | 'curve' | 'none';
export interface GalleryLayoutSettings {
// Common settings
@@ -15,10 +21,16 @@ export interface GalleryLayoutSettings {
};
// Masonry specific
masonryMode?: 'columns' | 'rows' | 'flickr' | 'quilted'; // columns = Pinterest-style, rows = justified rows, flickr = Flickr justified-layout, quilted = mixed sizes based on aspect ratio
masonryMode?: 'columns' | 'rows' | 'flickr' | 'quilted' | 'justified'; // columns = Pinterest-style, rows = justified rows, flickr = Flickr justified-layout, quilted = mixed sizes, justified = Knuth-Plass
masonryGutter?: number;
masonryRowHeight?: number; // Target row height for rows mode (150-400)
masonryLastRowBehavior?: 'justify' | 'left' | 'center'; // How to align incomplete last row
// Justified layout specific
justifiedRowHeight?: number;
justifiedLastRowBehavior?: 'justify' | 'left' | 'center';
justifiedShowHero?: boolean;
justifiedHeroHeight?: 'small' | 'medium' | 'large';
// Carousel specific
carouselAutoplay?: boolean;
@@ -58,9 +70,13 @@ export interface ThemeConfig {
// Gallery Layout
galleryLayout?: GalleryLayoutType;
gallerySettings?: GalleryLayoutSettings;
// Header/Footer
headerStyle?: 'minimal' | 'standard' | 'full';
// Header Style (decoupled from layout)
headerStyle?: HeaderStyleType;
heroDividerStyle?: HeroDividerStyle;
// Legacy Header/Footer (kept for backward compatibility)
legacyHeaderStyle?: 'minimal' | 'standard' | 'full';
footerStyle?: 'minimal' | 'standard' | 'full';
showEventInfo?: boolean;
showBranding?: boolean;
@@ -115,14 +131,16 @@ export const GALLERY_THEME_PRESETS: Record<string, EventTheme> = {
headingFontFamily: 'Playfair Display, serif',
borderRadius: 'lg',
shadowStyle: 'subtle',
galleryLayout: 'hero',
galleryLayout: 'grid',
headerStyle: 'hero',
heroDividerStyle: 'wave',
gallerySettings: {
spacing: 'relaxed',
photoAnimation: 'scale',
photoShape: 'rounded',
heroOverlayOpacity: 0.3
},
headerStyle: 'full',
legacyHeaderStyle: 'full',
footerStyle: 'minimal'
},
isPreset: true
@@ -172,13 +190,13 @@ export const GALLERY_THEME_PRESETS: Record<string, EventTheme> = {
carouselInterval: 5000,
carouselShowThumbnails: true
},
headerStyle: 'full',
headerStyle: 'standard',
footerStyle: 'standard',
backgroundPattern: 'dots'
},
isPreset: true
},
corporateTimeline: {
name: 'Corporate Timeline',
description: 'Professional chronological layout',