fix: lightbox watermark loading, white label translations, and dynamic footer year

- Fix watermarked images not opening in lightbox (add /api prefix to photo URLs)
- Add i18n translations for 'White Label' and 'Hide Powered by' branding settings
- Add complete logo customization translations (EN and DE)
- Replace hardcoded © 2024 with dynamic current year in footer
- Use company name from settings in default footer text
This commit is contained in:
Paul Nothaft
2026-01-15 14:16:00 +01:00
parent ea20446a79
commit ce8587b24d
7 changed files with 59 additions and 11 deletions
@@ -444,7 +444,7 @@ export const GalleryLayout: React.FC<GalleryLayoutProps> = ({
</p> </p>
)} )}
<p className="text-xs sm:text-sm text-neutral-500"> <p className="text-xs sm:text-sm text-neutral-500">
{brandingSettings?.footer_text || '© 2024 Your Company. All rights reserved.'} {brandingSettings?.footer_text || `© ${new Date().getFullYear()}${brandingSettings?.company_name ? ` ${brandingSettings.company_name}` : ''}. All rights reserved.`}
{!brandingSettings?.hide_powered_by && ( {!brandingSettings?.hide_powered_by && (
<> | Powered by <span className="font-semibold">PicPeak</span></> <> | Powered by <span className="font-semibold">PicPeak</span></>
)} )}
@@ -203,7 +203,7 @@ export const GalleryView: React.FC<GalleryViewProps> = ({ slug, event }) => {
company_name: settingsData.branding_company_name || '', company_name: settingsData.branding_company_name || '',
company_tagline: settingsData.branding_company_tagline || '', company_tagline: settingsData.branding_company_tagline || '',
support_email: settingsData.branding_support_email || '', support_email: settingsData.branding_support_email || '',
footer_text: settingsData.branding_footer_text || '© 2024 Your Company. All rights reserved.', footer_text: settingsData.branding_footer_text || '',
watermark_enabled: settingsData.branding_watermark_enabled || false, watermark_enabled: settingsData.branding_watermark_enabled || false,
logo_url: settingsData.branding_logo_url || null, logo_url: settingsData.branding_logo_url || null,
logo_size: settingsData.branding_logo_size || 'medium', logo_size: settingsData.branding_logo_size || 'medium',
@@ -385,7 +385,7 @@ export const GalleryView: React.FC<GalleryViewProps> = ({ slug, event }) => {
if (watermarkEnabled) { if (watermarkEnabled) {
photos = photos.map(photo => ({ photos = photos.map(photo => ({
...photo, ...photo,
url: `/gallery/${slug}/photo/${photo.id}` url: `/api/gallery/${slug}/photo/${photo.id}`
})); }));
} }
+25 -1
View File
@@ -1255,7 +1255,31 @@
"customizeTheme": "Design anpassen", "customizeTheme": "Design anpassen",
"saveTheme": "Design speichern", "saveTheme": "Design speichern",
"previewLayout": "Vorschau-Layout", "previewLayout": "Vorschau-Layout",
"livePreview": "Live-Vorschau" "livePreview": "Live-Vorschau",
"whiteLabel": "White Label",
"hidePoweredBy": "\"Powered by PicPeak\" Branding ausblenden",
"hidePoweredByHelp": "Entfernen Sie die PicPeak-Kennzeichnung aus Galerie-Fußzeilen für ein vollständig personalisiertes Erscheinungsbild",
"logoCustomization": "Logo-Anpassung",
"changeLogo": "Logo ändern",
"logoSizeSmall": "Klein (32px)",
"logoSizeMedium": "Mittel (48px)",
"logoSizeLarge": "Groß (64px)",
"logoSizeXLarge": "Extra Groß (96px)",
"logoSizeCustom": "Benutzerdefiniert",
"logoMaxHeight": "Maximale Höhe (Pixel)",
"logoMaxHeightHelp": "Legen Sie eine benutzerdefinierte maximale Höhe für das Logo fest (20-200 Pixel)",
"logoPosition": "Logo-Position im Header",
"positionLeft": "Links",
"positionCenter": "Mitte",
"positionRight": "Rechts",
"logoDisplayMode": "Anzeigemodus",
"logoOnly": "Nur Logo",
"textOnly": "Nur Firmenname",
"logoAndText": "Logo und Firmenname",
"showLogoInHeader": "Logo im Galerie-Header anzeigen",
"showLogoInHeaderHelp": "Logo in der Hauptkopfzeile anzeigen",
"showLogoInHero": "Logo im Hero-Bereich anzeigen",
"showLogoInHeroHelp": "Logo in Hero-Bereichen anzeigen (für Nicht-Raster-Layouts)"
}, },
"admin": { "admin": {
"title": "Admin-Panel", "title": "Admin-Panel",
+25 -1
View File
@@ -1018,7 +1018,31 @@
"customizeTheme": "Customize Theme", "customizeTheme": "Customize Theme",
"saveTheme": "Save Theme", "saveTheme": "Save Theme",
"previewLayout": "Preview Layout", "previewLayout": "Preview Layout",
"livePreview": "Live Preview" "livePreview": "Live Preview",
"whiteLabel": "White Label",
"hidePoweredBy": "Hide \"Powered by PicPeak\" branding",
"hidePoweredByHelp": "Remove the PicPeak attribution from gallery footers for a fully white-labeled experience",
"logoCustomization": "Logo Customization",
"changeLogo": "Change Logo",
"logoSizeSmall": "Small (32px)",
"logoSizeMedium": "Medium (48px)",
"logoSizeLarge": "Large (64px)",
"logoSizeXLarge": "Extra Large (96px)",
"logoSizeCustom": "Custom",
"logoMaxHeight": "Maximum Height (pixels)",
"logoMaxHeightHelp": "Set a custom maximum height for the logo (20-200 pixels)",
"logoPosition": "Logo Position in Header",
"positionLeft": "Left",
"positionCenter": "Center",
"positionRight": "Right",
"logoDisplayMode": "Display Mode",
"logoOnly": "Logo Only",
"textOnly": "Company Name Only",
"logoAndText": "Logo and Company Name",
"showLogoInHeader": "Show logo in gallery header",
"showLogoInHeaderHelp": "Display the logo in the main header bar",
"showLogoInHero": "Show logo in hero section",
"showLogoInHeroHelp": "Display the logo in hero sections (for non-grid layouts)"
}, },
"admin": { "admin": {
"title": "Admin Panel", "title": "Admin Panel",
+2 -2
View File
@@ -15,7 +15,7 @@ export const BrandingPage: React.FC = () => {
const [brandingSettings, setBrandingSettings] = useState<BrandingSettings>({ const [brandingSettings, setBrandingSettings] = useState<BrandingSettings>({
company_name: '', company_name: '',
company_tagline: '', company_tagline: '',
footer_text: '© 2024 Your Company. All rights reserved.', footer_text: '',
support_email: '', support_email: '',
watermark_enabled: false, watermark_enabled: false,
watermark_position: 'bottom-right', watermark_position: 'bottom-right',
@@ -307,7 +307,7 @@ export const BrandingPage: React.FC = () => {
onChange={(e) => handleBrandingChange('footer_text', e.target.value)} onChange={(e) => handleBrandingChange('footer_text', e.target.value)}
className="w-full px-3 py-2 border border-neutral-300 rounded-lg focus:ring-2 focus:ring-primary-500" className="w-full px-3 py-2 border border-neutral-300 rounded-lg focus:ring-2 focus:ring-primary-500"
rows={2} rows={2}
placeholder="© 2024 Your Company. All rights reserved." placeholder={`© ${new Date().getFullYear()} Your Company. All rights reserved.`}
/> />
</div> </div>
</div> </div>
+1 -1
View File
@@ -144,7 +144,7 @@ export const LegalPage: React.FC = () => {
</Link> </Link>
</div> </div>
<p className="text-sm text-neutral-500 mt-4"> <p className="text-sm text-neutral-500 mt-4">
© 2024 PicPeak. All rights reserved. © {new Date().getFullYear()} PicPeak. All rights reserved.
</p> </p>
</div> </div>
</footer> </footer>
+2 -2
View File
@@ -12,8 +12,8 @@ interface PhotoUrlOptions {
*/ */
export function getPhotoUrl({ slug, photo, watermarkEnabled = false, token }: PhotoUrlOptions): string { export function getPhotoUrl({ slug, photo, watermarkEnabled = false, token }: PhotoUrlOptions): string {
if (watermarkEnabled && token) { if (watermarkEnabled && token) {
// Use the watermarked photo endpoint // Use the watermarked photo endpoint (needs /api prefix)
return `/gallery/${slug}/photo/${photo.id}`; return `/api/gallery/${slug}/photo/${photo.id}`;
} }
// Use the static photo URL // Use the static photo URL