feat: sort photos by capture date with configurable default sort (#283)
Add per-event default photo sort setting with 6 options: - Upload Date (Newest/Oldest First) - Date Taken (Newest/Oldest First) — uses EXIF captured_at - Filename (A-Z / Z-A) Backend: - Migration 077 adds default_photo_sort column to events table - Event create/update handlers accept and validate the setting - Gallery info endpoint returns default_photo_sort for frontend Frontend: - "Date Taken" added to gallery sort dropdown (alongside Date, Name, Size, Rating) - Gallery initializes with event's default sort instead of hardcoded "date" - "Default Photo Sort" dropdown in event create and edit forms - Photos without EXIF dates fall back to upload date i18n: All 5 locales (EN, DE, NL, PT, RU) updated with sort labels. Closes #283
This commit is contained in:
@@ -259,7 +259,12 @@ router.post('/', adminAuth, requirePermission('events.create'), [
|
||||
body('hero_image_anchor').optional().custom(validateHeroImageAnchor),
|
||||
// Client access settings (#172)
|
||||
body('client_access_enabled').optional().isBoolean(),
|
||||
body('client_password').optional().isString()
|
||||
body('client_password').optional().isString(),
|
||||
body('default_photo_sort').optional().isIn([
|
||||
'upload_date_desc', 'upload_date_asc',
|
||||
'capture_date_desc', 'capture_date_asc',
|
||||
'filename_asc', 'filename_desc'
|
||||
])
|
||||
], async (req, res) => {
|
||||
try {
|
||||
logger.debug('Create event request body', { body: req.body });
|
||||
@@ -314,7 +319,9 @@ router.post('/', adminAuth, requirePermission('events.create'), [
|
||||
client_access_enabled = false,
|
||||
client_password = null,
|
||||
// Draft mode
|
||||
is_draft = true
|
||||
is_draft = true,
|
||||
// Default photo sort
|
||||
default_photo_sort = 'upload_date_desc'
|
||||
} = req.body;
|
||||
|
||||
const customerName = getCustomerNameFromPayload(req.body);
|
||||
@@ -483,6 +490,7 @@ router.post('/', adminAuth, requirePermission('events.create'), [
|
||||
hero_image_anchor: hero_image_anchor || 'center',
|
||||
photo_cap: photo_cap || null,
|
||||
is_draft: formatBoolean(parseBooleanInput(is_draft, true)),
|
||||
default_photo_sort: default_photo_sort || 'upload_date_desc',
|
||||
// Client access (#172)
|
||||
client_access_enabled: formatBoolean(client_access_enabled),
|
||||
...(client_access_enabled && client_password ? {
|
||||
@@ -856,7 +864,12 @@ router.put('/:id', adminAuth, requirePermission('events.edit'), requireEventOwne
|
||||
// Client access settings (#172)
|
||||
body('client_access_enabled').optional().isBoolean(),
|
||||
body('client_password').optional().isString(),
|
||||
body('regenerate_client_token').optional().isBoolean()
|
||||
body('regenerate_client_token').optional().isBoolean(),
|
||||
body('default_photo_sort').optional().isIn([
|
||||
'upload_date_desc', 'upload_date_asc',
|
||||
'capture_date_desc', 'capture_date_asc',
|
||||
'filename_asc', 'filename_desc'
|
||||
])
|
||||
], async (req, res) => {
|
||||
try {
|
||||
const errors = validationResult(req);
|
||||
|
||||
@@ -123,7 +123,8 @@ router.get('/:slug/info', async (req, res) => {
|
||||
'header_style',
|
||||
'hero_divider_style',
|
||||
'hero_image_anchor',
|
||||
'is_draft'
|
||||
'is_draft',
|
||||
'default_photo_sort'
|
||||
)
|
||||
.first();
|
||||
|
||||
@@ -182,7 +183,8 @@ router.get('/:slug/info', async (req, res) => {
|
||||
hero_logo_url: event.hero_logo_url || null,
|
||||
header_style: event.header_style || 'standard',
|
||||
hero_divider_style: event.hero_divider_style || 'wave',
|
||||
hero_image_anchor: event.hero_image_anchor || 'center'
|
||||
hero_image_anchor: event.hero_image_anchor || 'center',
|
||||
default_photo_sort: event.default_photo_sort || 'upload_date_desc'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching gallery info:', error);
|
||||
@@ -397,6 +399,7 @@ router.get('/:slug/photos', verifyGalleryAccess, async (req, res) => {
|
||||
header_style: req.event.header_style || 'standard',
|
||||
hero_divider_style: req.event.hero_divider_style || 'wave',
|
||||
hero_image_anchor: req.event.hero_image_anchor || 'center',
|
||||
default_photo_sort: req.event.default_photo_sort || 'upload_date_desc',
|
||||
...protectionSettings
|
||||
},
|
||||
categories: categories,
|
||||
|
||||
Reference in New Issue
Block a user