Fixes#84, Fixes#85
- Fix uploads proxy routing in nginx and vite dev server
- Fix logo/favicon state handling in BrandingPage
- Fix invitation API response field transformation (snake_case → camelCase)
- Add hide_powered_by to public settings API
- Mark Multiple Administrators as implemented in roadmap
- Bump version to 2.2.1
Fixes#84 - Logo and favicon not displaying on branding page and galleries
Fixes#85 - Invitations showing undefined expiresAt causing parseISO errors
Changes:
- Fix nginx.conf: Add ^~ modifier to /uploads location to prioritize proxy over static file matching
- Fix vite.config.ts: Add /uploads proxy for development environment
- Fix BrandingPage.tsx: Include logo_url from branding settings instead of expecting it from theme
- Fix adminUsers.js: Add transformInvitation() to convert snake_case DB fields to camelCase API response
- Fix publicSettings.js: Add branding_hide_powered_by to public settings API response
- Update README.md: Mark Multiple Administrators feature as implemented
- Bump version to 2.2.1
When uploading a new logo, the code tries to delete the old logo file.
This failed when the old path was stored as a raw path (legacy format)
instead of JSON-serialized. Added check to handle both formats.
QEMU emulation of ARM64 on x86 GitHub runners is too slow and
unreliable for npm operations, causing builds to hang or crash
with "Illegal instruction" errors.
Changed platform detection logic to:
- Tagged releases (v*.*.*): Build both amd64 and arm64
- All other builds (branches, PRs): Build amd64 only
This ensures fast CI feedback during development while still
providing multi-arch images for production releases.
Fixes#84
The favicon and logo upload endpoints were storing URL paths directly
without JSON.stringify(), causing PostgreSQL JSON validation errors
("Token '/' is invalid") since paths like "/uploads/favicons/..."
are not valid JSON.
Applied JSON.stringify() to:
- branding_logo_url setting (lines 358, 364)
- branding_favicon_url setting (lines 894, 900)
- Add settings.events.* keys for Event Creation settings
- Add settings.imageSecurity.* keys for Image Protection settings
- Add settings.moderation.* keys for Word Filter/Moderation settings
- Add cssTemplates.* keys for Custom CSS Templates
- All settings tabs now have proper i18n support
- Manual backup button now works regardless of backup_enabled setting
- backup_enabled only controls scheduled/automated backups
- Manual backups only require destination to be configured
- Fixed backup_type to correctly show 'manual' vs 'scheduled'
- Try connecting to target database first (most common case)
- Fall back to template1 instead of postgres database for checks
- The picpeak user may not have access to postgres system database
- Add better retry logic with max attempts
- Improve error messages
- Add multi-administrator support with role-based access control
- Add CSS template system with Apple Liquid Glass designs
- Add CSS template selector to event editing
- Fix photo category selection and feedback button visibility (#77)
- Security hardening and Alpine base image upgrade
- Add CSS template selector to ThemeCustomizerEnhanced component
- Rename "Custom CSS" to "Event-specific Custom CSS" for clarity
- Load and save css_template_id when editing events
- Fetch CSS templates when entering edit mode on EventDetailsPage
- Pass CSS template props to ThemeEditorModal
- Add backend validation for css_template_id field
- Fix upload category selection by looking up category from database
and saving category_id to photos table (was being ignored before)
- Use category slug for filename generation during upload
- Improve Like/Comment button visibility in CarouselGalleryLayout and
PhotoLightbox with semi-transparent background and border styling
- Backend PATCH /photos/:photoId now returns updated photo object
- Photo listing now joins with photo_categories table to get actual
category name and slug instead of hardcoding based on photo.type
- Frontend service now properly returns AdminPhoto from update response
Fixes#77
## Changes
### CSS Template System
- Added CSS class hooks to gallery components for custom template targeting
- Gallery sidebar, header, footer, and photo cards can now be styled via CSS templates
- CSS variables on :root allow themes to override colors, effects, and spacing
### Gallery Component CSS Classes Added
- `.gallery-page` - Main gallery container
- `.gallery-header` - Top header bar
- `.gallery-sidebar` - Filter/download sidebar
- `.gallery-sidebar-header`, `.gallery-sidebar-title`, `.gallery-sidebar-close`
- `.gallery-sidebar-content`, `.gallery-sidebar-section`
- `.gallery-sidebar-search-input`, `.gallery-sidebar-search-icon`
- `.gallery-sidebar-backdrop` - Mobile overlay
- `.gallery-btn`, `.gallery-btn-download` - Sidebar buttons
- `.gallery-footer` - Footer section
- `.photo-card`, `.photo-grid` - Photo display elements
### CSS Templates (Database)
- Elegant Dark (id=1): Dark navy theme with light text and red accents
- Liquid Glass Light (id=2): iOS 26 frosted glass effect with gradient background
### Bug Fixes
- Fixed CSS variables not inheriting (moved from .gallery-page to :root)
- Fixed sidebar position breaking layout (removed position: relative override)
- Fixed Elegant Dark sidebar text visibility (white on white issue)
### Other Changes
- Settings page refactoring and cleanup
- i18n locale updates for new gallery features
- Vite proxy port configuration fix
- Admin auth route improvements
- CSS templates service updates
- Add safeParseDate helper to handle dates that may be strings, Date objects, or timestamps
- Replace all parseISO(event.*) calls with safeParseDate() to prevent "dateString.split is not a function" errors
- Fix Vite proxy target from port 3002 to 3001 to match backend server port
Comprehensive feature plan for filtering photos by guest feedback
(ratings, likes, favorites) and exporting selections for professional
photo editing workflows.
Export formats supported:
- TXT: Simple filename list for Lightroom filter paste
- CSV: Spreadsheet with metadata columns
- XMP: Sidecar files with ratings/labels for Lightroom/Capture One
- ZIP: Original photos with folder organization
- JSON: Structured metadata for automation
Key features:
- Admin filter UI with rating thresholds and feedback toggles
- AND/OR filter logic
- Quick presets (Guest Picks, Top Rated, Most Popular)
- Photo selection with batch actions
- XMP rating mapping (PicPeak 1-5 → XMP 1-5 + color labels)
- Background job support for large exports
- Export settings dialog with customization options
Research references:
- Adobe XMP/Lightroom metadata standards
- Capture One EIP format
- IPTC Photo Metadata Standard
- ExifTool capabilities
This document outlines the implementation plan for allowing administrators
to rename gallery events with full Option B implementation:
- Database updates (events, photos, new slug_redirects table)
- File system changes (folders and photo files)
- New API endpoint: POST /api/admin/events/:id/rename
- Frontend UI components (button, dialog, progress indicator)
- Email notification option for resending invitation
- Slug redirect support for backward compatibility
- Transaction handling with rollback mechanism
The feature includes:
- Rename button on event detail page
- Confirmation dialog with new name input
- Real-time slug preview
- Checkbox to resend invitation email
- Progress indicator during operation
- Redirect to renamed event on success