Fix brand theme application and add comprehensive translations

- Fixed theme not being reflected on gallery and admin login pages
- Created GlobalThemeProvider to apply themes globally
- Updated gallery and admin login pages to use dynamic CSS variables
- Added complete translations for all admin sections in English and German:
  - Notifications management
  - Event view and creation
  - Photo upload functionality
  - Category management
  - Archive page view
  - Analytics dashboard
  - Branding and theme settings
  - System settings
  - CMS page management
  - Email configuration
- Fixed admin photo management display issues
- Fixed photo upload category assignment
- Added password reset functionality for galleries
- Improved error handling and user feedback

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
This commit is contained in:
2025-07-08 17:07:40 +02:00
co-authored by Claude
parent 2012b0bab9
commit d594d00227
79 changed files with 4570 additions and 329 deletions
+31 -4
View File
@@ -15,6 +15,7 @@ import { format, parseISO, differenceInDays } from 'date-fns';
import { toast } from 'react-toastify';
import { Button, Input, Card, SkeletonTable, ErrorBoundary } from '../../components/common';
import { BulkArchiveModal } from '../../components/admin';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { eventsService } from '../../services/events.service';
import type { Event } from '../../types';
@@ -28,6 +29,7 @@ export const EventsListPage: React.FC = () => {
const [selectedEvents, setSelectedEvents] = useState<number[]>([]);
// const [showFilters, setShowFilters] = useState(false);
const [activeDropdown, setActiveDropdown] = useState<number | null>(null);
const [showBulkArchiveModal, setShowBulkArchiveModal] = useState(false);
// Get filter from URL
const statusFilter = searchParams.get('filter') as 'active' | 'archived' | null;
@@ -63,6 +65,25 @@ export const EventsListPage: React.FC = () => {
},
});
// Bulk archive mutation
const bulkArchiveMutation = useMutation({
mutationFn: eventsService.bulkArchiveEvents,
onSuccess: (data) => {
queryClient.invalidateQueries({ queryKey: ['admin-events'] });
setSelectedEvents([]);
setShowBulkArchiveModal(false);
if (data.results.failed.length === 0) {
toast.success(`Successfully archived ${data.results.successful.length} events`);
} else {
toast.warning(`Archived ${data.results.successful.length} events, ${data.results.failed.length} failed`);
}
},
onError: () => {
toast.error('Failed to archive events');
},
});
// Filter and search events
const filteredEvents = useMemo(() => {
if (!data?.events) return [];
@@ -237,10 +258,7 @@ export const EventsListPage: React.FC = () => {
<Button
variant="outline"
size="sm"
onClick={() => {
// Handle bulk archive
toast.info('Bulk archive coming soon');
}}
onClick={() => setShowBulkArchiveModal(true)}
>
Archive Selected
</Button>
@@ -407,6 +425,15 @@ export const EventsListPage: React.FC = () => {
</table>
</div>
</Card>
{/* Bulk Archive Modal */}
<BulkArchiveModal
isOpen={showBulkArchiveModal}
onClose={() => setShowBulkArchiveModal(false)}
onConfirm={() => bulkArchiveMutation.mutate(selectedEvents)}
selectedEvents={filteredEvents.filter(e => selectedEvents.includes(e.id))}
isLoading={bulkArchiveMutation.isPending}
/>
</div>
</ErrorBoundary>
);