Integrate branding and theme settings with database
- Update BrandingPage to save settings to database instead of localStorage - Add public settings endpoint for galleries to fetch branding/theme - Update GalleryView to apply branding settings in footer - Apply theme settings from database to gallery pages - Support event-specific themes that override global settings - Ensure watermark and all branding settings are stored in database
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
import React, { useState, useMemo, useEffect } from 'react';
|
||||
import { Download, Grid, Square, LogOut, Calendar, Clock, Search, SortAsc } from 'lucide-react';
|
||||
import { format, differenceInDays, parseISO } from 'date-fns';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { Button, Input, SkeletonGalleryGrid, Skeleton } from '../common';
|
||||
import { useGalleryAuth } from '../../contexts';
|
||||
import { useGalleryAuth, useTheme } from '../../contexts';
|
||||
import { useGalleryPhotos, useDownloadAllPhotos } from '../../hooks/useGallery';
|
||||
import { PhotoGrid } from './PhotoGrid';
|
||||
import { ExpirationBanner } from './ExpirationBanner';
|
||||
import { CountdownTimer } from './CountdownTimer';
|
||||
import { analyticsService } from '../../services/analytics.service';
|
||||
import { api } from '../../config/api';
|
||||
|
||||
interface GalleryViewProps {
|
||||
slug: string;
|
||||
@@ -25,15 +27,58 @@ interface GalleryViewProps {
|
||||
|
||||
export const GalleryView: React.FC<GalleryViewProps> = ({ slug, event }) => {
|
||||
const { logout } = useGalleryAuth();
|
||||
const { setTheme } = useTheme();
|
||||
const [viewMode, setViewMode] = useState<'all' | 'collages' | 'individual'>('all');
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [sortBy, setSortBy] = useState<'date' | 'name' | 'size'>('date');
|
||||
const [showSortMenu, setShowSortMenu] = useState(false);
|
||||
const [brandingSettings, setBrandingSettings] = useState<any>(null);
|
||||
|
||||
// Fetch photos
|
||||
const { data, isLoading, error } = useGalleryPhotos(slug);
|
||||
const downloadAllMutation = useDownloadAllPhotos();
|
||||
|
||||
// Fetch branding settings
|
||||
const { data: settingsData } = useQuery({
|
||||
queryKey: ['gallery-settings'],
|
||||
queryFn: async () => {
|
||||
const response = await api.get('/api/public/settings');
|
||||
return response.data;
|
||||
},
|
||||
staleTime: 5 * 60 * 1000, // Cache for 5 minutes
|
||||
});
|
||||
|
||||
// Apply theme and branding settings
|
||||
useEffect(() => {
|
||||
if (settingsData) {
|
||||
// Apply branding settings
|
||||
setBrandingSettings({
|
||||
company_name: settingsData.branding_company_name || '',
|
||||
company_tagline: settingsData.branding_company_tagline || '',
|
||||
support_email: settingsData.branding_support_email || '',
|
||||
footer_text: settingsData.branding_footer_text || '© 2024 Your Company. All rights reserved.',
|
||||
watermark_enabled: settingsData.branding_watermark_enabled || false,
|
||||
});
|
||||
|
||||
// Apply theme settings
|
||||
if (settingsData.theme_config) {
|
||||
setTheme(settingsData.theme_config);
|
||||
}
|
||||
}
|
||||
}, [settingsData, setTheme]);
|
||||
|
||||
// Apply event-specific theme if available
|
||||
useEffect(() => {
|
||||
if (event.color_theme) {
|
||||
try {
|
||||
const eventTheme = JSON.parse(event.color_theme);
|
||||
setTheme(eventTheme);
|
||||
} catch (e) {
|
||||
console.error('Failed to parse event theme:', e);
|
||||
}
|
||||
}
|
||||
}, [event.color_theme, setTheme]);
|
||||
|
||||
// Calculate days until expiration
|
||||
const daysUntilExpiration = differenceInDays(parseISO(event.expires_at), new Date());
|
||||
const showUrgentWarning = daysUntilExpiration <= 7;
|
||||
@@ -305,15 +350,25 @@ export const GalleryView: React.FC<GalleryViewProps> = ({ slug, event }) => {
|
||||
{/* Footer */}
|
||||
<footer className="mt-12 py-8 border-t border-neutral-200">
|
||||
<div className="container text-center">
|
||||
<p className="text-sm text-neutral-600">
|
||||
Need help? Contact the event organizer at{' '}
|
||||
<a
|
||||
href={`mailto:${data.event.event_name}`}
|
||||
className="text-primary-600 hover:text-primary-700"
|
||||
>
|
||||
support email
|
||||
</a>
|
||||
{brandingSettings?.support_email && (
|
||||
<p className="text-sm text-neutral-600 mb-2">
|
||||
Need help? Contact us at{' '}
|
||||
<a
|
||||
href={`mailto:${brandingSettings.support_email}`}
|
||||
className="text-primary-600 hover:text-primary-700"
|
||||
>
|
||||
{brandingSettings.support_email}
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
<p className="text-sm text-neutral-500">
|
||||
{brandingSettings?.footer_text || '© 2024 Your Company. All rights reserved.'}
|
||||
</p>
|
||||
{brandingSettings?.company_name && brandingSettings?.company_tagline && (
|
||||
<p className="text-xs text-neutral-400 mt-2">
|
||||
{brandingSettings.company_name} - {brandingSettings.company_tagline}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user