diff --git a/sql/remove-duplicate-images.sql b/sql/remove-duplicate-images.sql new file mode 100644 index 0000000..8ac0e84 --- /dev/null +++ b/sql/remove-duplicate-images.sql @@ -0,0 +1,20 @@ +-- Remove duplicate images, keeping only the most recent one per (filename, location_target, data length) +-- This handles upload accidents where same image was uploaded multiple times + +-- First, identify duplicates +-- SELECT filename, location_target, COUNT(*) as dupes, array_agg(id) as ids +-- FROM images GROUP BY filename, location_target, LENGTH(data) HAVING COUNT(*) > 1; + +-- Delete duplicates, keeping the latest (highest id) per group +DELETE FROM images a +USING images b +WHERE a.id < b.id + AND a.filename = b.filename + AND a.location_target = b.location_target + AND LENGTH(a.data) = LENGTH(b.data); + +-- Verify cleanup +SELECT filename, location_target, COUNT(*) as count +FROM images +GROUP BY filename, location_target, LENGTH(data) +HAVING COUNT(*) > 1; \ No newline at end of file diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 6ddfcb5..6cb1e59 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -272,6 +272,7 @@ function ImageGallery({ images, onDelete }: { images: Image[]; onDelete: (id: nu const sectionCategories = [ { key: 'slides', label: '🎞️ Slideshow Gallery', filter: (i: Image) => i.category === 'slides' || i.location_target === 'slides' }, + { key: 'food', label: '🍽️ Food Gallery', filter: (i: Image) => i.category === 'food' || i.location_target === 'food' }, { key: 'calendar', label: '📅 Calendar Events Gallery', filter: (i: Image) => i.category === 'calendar' || i.location_target === 'calendar' }, { key: 'social', label: '🎪 Social Events Gallery', filter: (i: Image) => i.category === 'social' || i.location_target === 'social' }, ]; @@ -290,6 +291,7 @@ function ImageGallery({ images, onDelete }: { images: Image[]; onDelete: (id: nu const filteredImages = images.filter((img) => { if (selectedCategory === 'all') return true; if (selectedCategory === 'rooms') return img.category === 'rooms' || img.location_target?.startsWith('room-'); + if (selectedCategory === 'food') return img.category === 'food' || img.location_target === 'food'; return img.category === selectedCategory || img.location_target === selectedCategory; }); @@ -387,7 +389,7 @@ function ImageGallery({ images, onDelete }: { images: Image[]; onDelete: (id: nu border: `1px solid ${C.border}`, background: '#fff', boxShadow: C.shadow, }}> - {['all', 'slides', 'calendar', 'social', 'rooms', 'other'].map((cat) => ( + {['all', 'slides', 'food', 'calendar', 'social', 'rooms', 'other'].map((cat) => ( setSelectedCategory(cat)}