feat: add per-event custom logo upload with bug fixes

Add event-level custom logo upload/delete endpoints and UI, allowing
per-event logos to override the global branding logo in gallery views.

Also fixes several bugs discovered during testing:
- fix: category_id 'individual' parsed as NaN causing photo upload failures
- fix: gallery auth race condition where photos query fired before token stored
- fix: gallery-photos query not invalidated after favorite/like mutations
- fix: e2e test race conditions with View Gallery button detachment
This commit is contained in:
Paul Nothaft
2026-01-23 22:01:02 +01:00
parent c5a8ffc08c
commit 85170b883f
13 changed files with 356 additions and 28 deletions
@@ -0,0 +1,53 @@
/**
* Migration: Add custom logo support to events table
*
* Allows per-event custom logo that overrides the global branding logo:
* - hero_logo_url: Public path to the uploaded custom logo
* - hero_logo_path: Full filesystem path to the custom logo
*
* Logo priority: Event custom logo > Global branding logo > Default PicPeak logo
*
* Addresses GitHub Issue #138: Per-event custom logo option
*/
exports.up = async function (knex) {
console.log('Adding custom logo columns to events table...');
const hasUrlColumn = await knex.schema.hasColumn('events', 'hero_logo_url');
if (!hasUrlColumn) {
await knex.schema.table('events', (table) => {
table.string('hero_logo_url', 500).nullable().defaultTo(null);
});
console.log('Added hero_logo_url column');
}
const hasPathColumn = await knex.schema.hasColumn('events', 'hero_logo_path');
if (!hasPathColumn) {
await knex.schema.table('events', (table) => {
table.string('hero_logo_path', 500).nullable().defaultTo(null);
});
console.log('Added hero_logo_path column');
}
console.log('Migration 063_add_event_custom_logo completed successfully');
};
exports.down = async function (knex) {
console.log('Rolling back custom logo columns...');
const hasUrlColumn = await knex.schema.hasColumn('events', 'hero_logo_url');
if (hasUrlColumn) {
await knex.schema.table('events', (table) => {
table.dropColumn('hero_logo_url');
});
}
const hasPathColumn = await knex.schema.hasColumn('events', 'hero_logo_path');
if (hasPathColumn) {
await knex.schema.table('events', (table) => {
table.dropColumn('hero_logo_path');
});
}
console.log('Custom logo columns dropped');
};