feat: add per-event hero logo customization options

Add configurable hero logo settings for individual events:
- Logo visibility toggle (show/hide in hero section)
- Logo size options (small, medium, large, xlarge)
- Logo position options (top, center, bottom)

Changes include:
- Database migration for hero_logo_visible, hero_logo_size, hero_logo_position fields
- Backend routes updated to handle new settings
- Frontend admin page with logo customization controls
- HeroGalleryLayout component with dynamic logo rendering
- i18n translations for EN and DE

Also updates .gitignore to exclude test files and artifacts.
This commit is contained in:
Paul Nothaft
2026-01-22 13:54:23 +01:00
parent f8881d5bd6
commit 0790a1ddad
11 changed files with 353 additions and 27 deletions
@@ -0,0 +1,70 @@
/**
* Migration: Add hero logo customization settings to events table
*
* Allows per-event customization of the hero gallery logo:
* - hero_logo_visible: Show/hide the logo overlay
* - hero_logo_size: Logo size (small, medium, large, xlarge)
* - hero_logo_position: Logo position (top, center, bottom)
*
* Addresses GitHub Issue #138: Add Option to customize the Hero gallery layout
*/
exports.up = async function (knex) {
console.log('Adding hero logo settings to events table...');
// Add hero_logo_visible column
const hasVisibleColumn = await knex.schema.hasColumn('events', 'hero_logo_visible');
if (!hasVisibleColumn) {
await knex.schema.table('events', (table) => {
table.boolean('hero_logo_visible').notNullable().defaultTo(true);
});
console.log('Added hero_logo_visible column');
}
// Add hero_logo_size column
const hasSizeColumn = await knex.schema.hasColumn('events', 'hero_logo_size');
if (!hasSizeColumn) {
await knex.schema.table('events', (table) => {
table.string('hero_logo_size', 20).notNullable().defaultTo('medium');
});
console.log('Added hero_logo_size column');
}
// Add hero_logo_position column
const hasPositionColumn = await knex.schema.hasColumn('events', 'hero_logo_position');
if (!hasPositionColumn) {
await knex.schema.table('events', (table) => {
table.string('hero_logo_position', 20).notNullable().defaultTo('top');
});
console.log('Added hero_logo_position column');
}
console.log('Migration 062_add_hero_logo_settings completed successfully');
};
exports.down = async function (knex) {
console.log('Rolling back hero logo settings...');
const hasVisibleColumn = await knex.schema.hasColumn('events', 'hero_logo_visible');
if (hasVisibleColumn) {
await knex.schema.table('events', (table) => {
table.dropColumn('hero_logo_visible');
});
}
const hasSizeColumn = await knex.schema.hasColumn('events', 'hero_logo_size');
if (hasSizeColumn) {
await knex.schema.table('events', (table) => {
table.dropColumn('hero_logo_size');
});
}
const hasPositionColumn = await knex.schema.hasColumn('events', 'hero_logo_position');
if (hasPositionColumn) {
await knex.schema.table('events', (table) => {
table.dropColumn('hero_logo_position');
});
}
console.log('Hero logo settings columns dropped');
};