Fix language setting not being saved to database on admin settings page

- Added default_language field to general settings state in SettingsPage
- Replaced LanguageSelector component with simple select dropdown on settings page
- Fixed public settings endpoint to read general_default_language from database
- Language setting now properly saved when clicking Save Settings button
- Setting is correctly used by gallery login page and legal pages

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-07-08 09:49:45 +02:00
parent cfa0b0da69
commit 2012b0bab9
91 changed files with 6183 additions and 577 deletions
+182
View File
@@ -0,0 +1,182 @@
const express = require('express');
const { body, validationResult } = require('express-validator');
const { db, logActivity } = require('../database/db');
const { adminAuth } = require('../middleware/auth');
const router = express.Router();
// Get all global categories
router.get('/global', adminAuth, async (req, res) => {
try {
const categories = await db('photo_categories')
.where('is_global', true)
.orderBy('name', 'asc');
res.json(categories);
} catch (error) {
console.error('Error fetching categories:', error);
res.status(500).json({ error: 'Failed to fetch categories' });
}
});
// Get categories for a specific event (global + event-specific)
router.get('/event/:eventId', adminAuth, async (req, res) => {
try {
const { eventId } = req.params;
const categories = await db('photo_categories')
.where(function() {
this.where('is_global', true)
.orWhere('event_id', eventId);
})
.orderBy('is_global', 'desc')
.orderBy('name', 'asc');
res.json(categories);
} catch (error) {
console.error('Error fetching event categories:', error);
res.status(500).json({ error: 'Failed to fetch categories' });
}
});
// Create a new category
router.post('/', adminAuth, [
body('name').notEmpty().withMessage('Category name is required'),
body('slug').optional(),
body('is_global').optional().isBoolean(),
body('event_id').optional().isInt()
], async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { name, slug, is_global = true, event_id = null } = req.body;
// Generate slug if not provided
const categorySlug = slug || name.toLowerCase()
.replace(/[^\w\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-')
.trim();
// Check if slug already exists for this scope
const existing = await db('photo_categories')
.where('slug', categorySlug)
.where(function() {
if (is_global) {
this.where('is_global', true);
} else {
this.where('event_id', event_id);
}
})
.first();
if (existing) {
return res.status(400).json({ error: 'Category with this slug already exists' });
}
// Create category
const [categoryId] = await db('photo_categories').insert({
name,
slug: categorySlug,
is_global,
event_id: is_global ? null : event_id
});
const category = await db('photo_categories').where('id', categoryId).first();
// Log activity
await logActivity('category_created',
{ categoryName: name, isGlobal: is_global },
event_id,
{ type: 'admin', id: req.admin.id, name: req.admin.username }
);
res.json(category);
} catch (error) {
console.error('Error creating category:', error);
res.status(500).json({ error: 'Failed to create category' });
}
});
// Update a category
router.put('/:id', adminAuth, [
body('name').notEmpty().withMessage('Category name is required')
], async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { id } = req.params;
const { name } = req.body;
const category = await db('photo_categories').where('id', id).first();
if (!category) {
return res.status(404).json({ error: 'Category not found' });
}
await db('photo_categories')
.where('id', id)
.update({
name,
slug: name.toLowerCase()
.replace(/[^\w\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-')
.trim()
});
const updated = await db('photo_categories').where('id', id).first();
// Log activity
await logActivity('category_updated',
{ categoryName: name },
category.event_id,
{ type: 'admin', id: req.admin.id, name: req.admin.username }
);
res.json(updated);
} catch (error) {
console.error('Error updating category:', error);
res.status(500).json({ error: 'Failed to update category' });
}
});
// Delete a category
router.delete('/:id', adminAuth, async (req, res) => {
try {
const { id } = req.params;
const category = await db('photo_categories').where('id', id).first();
if (!category) {
return res.status(404).json({ error: 'Category not found' });
}
// Check if category has photos
const photoCount = await db('photos').where('category_id', id).count('id as count').first();
if (photoCount.count > 0) {
return res.status(400).json({
error: 'Cannot delete category with photos. Please reassign photos first.'
});
}
await db('photo_categories').where('id', id).delete();
// Log activity
await logActivity('category_deleted',
{ categoryName: category.name },
category.event_id,
{ type: 'admin', id: req.admin.id, name: req.admin.username }
);
res.json({ message: 'Category deleted successfully' });
} catch (error) {
console.error('Error deleting category:', error);
res.status(500).json({ error: 'Failed to delete category' });
}
});
module.exports = router;