Fix brand theme application and add comprehensive translations

- Fixed theme not being reflected on gallery and admin login pages
- Created GlobalThemeProvider to apply themes globally
- Updated gallery and admin login pages to use dynamic CSS variables
- Added complete translations for all admin sections in English and German:
  - Notifications management
  - Event view and creation
  - Photo upload functionality
  - Category management
  - Archive page view
  - Analytics dashboard
  - Branding and theme settings
  - System settings
  - CMS page management
  - Email configuration
- Fixed admin photo management display issues
- Fixed photo upload category assignment
- Added password reset functionality for galleries
- Improved error handling and user feedback

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-07-08 17:07:40 +02:00
parent 2012b0bab9
commit d594d00227
79 changed files with 4570 additions and 329 deletions
+37 -7
View File
@@ -4,7 +4,17 @@ const { db } = require('../database/db');
async function photoAuth(req, res, next) {
try {
const eventSlug = req.path.split('/')[1];
// Extract event slug from the path
let eventSlug;
// For thumbnails, we need to parse the filename to get the event info
if (req.path.startsWith('/thumb_')) {
// For now, we'll rely on JWT token for thumbnail access
eventSlug = null;
} else {
// For regular photos, the slug is the first part of the path
eventSlug = req.path.split('/')[1];
}
// First check for JWT token (from gallery access)
const authHeader = req.headers.authorization;
@@ -13,17 +23,32 @@ async function photoAuth(req, res, next) {
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
// Check if it's a gallery token for this event
if (decoded.type === 'gallery' && decoded.eventSlug === eventSlug) {
const event = await db('events').where({ slug: eventSlug, is_active: true }).first();
if (event) {
req.event = event;
return next();
// Check if it's a gallery token
if (decoded.type === 'gallery') {
// For thumbnails, we accept any valid gallery token
if (!eventSlug) {
const event = await db('events').where({ slug: decoded.eventSlug, is_active: true }).first();
if (event) {
req.event = event;
return next();
}
}
// For regular photos, check if token matches the event
else if (decoded.eventSlug === eventSlug) {
const event = await db('events').where({ slug: eventSlug, is_active: true }).first();
if (event) {
req.event = event;
return next();
}
}
}
// Check if it's an admin token (admins can view all photos)
if (decoded.type === 'admin') {
if (!eventSlug) {
// For thumbnails with admin token, allow access
return next();
}
const event = await db('events').where({ slug: eventSlug }).first();
if (event) {
req.event = event;
@@ -42,6 +67,11 @@ async function photoAuth(req, res, next) {
return res.status(401).json({ error: 'Authentication required' });
}
// If no eventSlug (thumbnails), we require JWT token
if (!eventSlug) {
return res.status(401).json({ error: 'Authentication required for thumbnails' });
}
const event = await db('events').where({ slug: eventSlug, is_active: true }).first();
if (!event) {
return res.status(404).json({ error: 'Gallery not found' });