diff --git a/backend/src/routes/adminPhotos.js b/backend/src/routes/adminPhotos.js index 57fe885..bb2834e 100644 --- a/backend/src/routes/adminPhotos.js +++ b/backend/src/routes/adminPhotos.js @@ -473,21 +473,34 @@ router.patch('/:eventId/photos/:photoId', adminAuth, async (req, res) => { try { const { eventId, photoId } = req.params; const { category_id } = req.body; - + // Verify photo belongs to event const photo = await db('photos') .where({ id: photoId, event_id: eventId }) .first(); - + if (!photo) { return res.status(404).json({ error: 'Photo not found' }); } - + + // Prepare update data + const updateData = {}; + + // Handle type-based categories ('individual' or 'collage') + // These are string values that map to the photo.type field + if (category_id === 'individual' || category_id === 'collage') { + updateData.type = category_id; + updateData.category_id = null; // Clear legacy category_id + } else { + // Handle legacy numeric category IDs + updateData.category_id = category_id || null; + } + // Update photo await db('photos') .where({ id: photoId }) - .update({ category_id: category_id || null }); - + .update(updateData); + res.json({ message: 'Photo updated successfully' }); } catch (error) { console.error('Error updating photo:', error); @@ -584,17 +597,25 @@ router.post('/:eventId/photos/bulk-update', adminAuth, async (req, res) => { return res.status(400).json({ error: 'Some photos do not belong to this event' }); } - // Update photos + // Prepare update data const updateData = {}; if (updates.category_id !== undefined) { - updateData.category_id = updates.category_id || null; + // Handle type-based categories ('individual' or 'collage') + // These are string values that map to the photo.type field + if (updates.category_id === 'individual' || updates.category_id === 'collage') { + updateData.type = updates.category_id; + updateData.category_id = null; // Clear legacy category_id + } else { + // Handle legacy numeric category IDs + updateData.category_id = updates.category_id || null; + } } - + await db('photos') .whereIn('id', photoIds) .where('event_id', eventId) .update(updateData); - + res.json({ message: `${photoIds.length} photos updated successfully` }); } catch (error) { console.error('Error bulk updating photos:', error); diff --git a/backend/src/services/photoResolver.js b/backend/src/services/photoResolver.js index 18e3f3c..340fd9e 100644 --- a/backend/src/services/photoResolver.js +++ b/backend/src/services/photoResolver.js @@ -12,8 +12,12 @@ const getStoragePath = () => process.env.STORAGE_PATH || path.join(__dirname, '. function resolvePhotoFilePath(event, photo) { if (!event || !photo) throw new Error('resolvePhotoFilePath requires event and photo'); - const mode = (event.source_mode || photo.source_origin || 'managed'); - if (mode === 'reference' || photo.source_origin === 'external') { + // IMPORTANT: photo.source_origin takes precedence over event.source_mode + // This allows events in "reference" mode to have mixed sources: + // - Imported photos: source_origin = 'external' + // - Uploaded photos: source_origin = 'managed' + const mode = (photo.source_origin || event.source_mode || 'managed'); + if (mode === 'reference' || mode === 'external') { if (!photo.external_relpath) { throw new Error('Missing external_relpath for external photo'); } diff --git a/frontend/src/components/gallery/layouts/HeroGalleryLayout.tsx b/frontend/src/components/gallery/layouts/HeroGalleryLayout.tsx index 630fcf9..660951c 100644 --- a/frontend/src/components/gallery/layouts/HeroGalleryLayout.tsx +++ b/frontend/src/components/gallery/layouts/HeroGalleryLayout.tsx @@ -162,13 +162,26 @@ export const HeroGalleryLayout: React.FC = ({ {/* Scroll Indicator */} -
+
+ {/* Grid Section */} -
+