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
+26 -11
View File
@@ -9,26 +9,36 @@ import {
AlertCircle,
RotateCcw,
Trash2,
Eye,
ChevronLeft,
ChevronRight
} from 'lucide-react';
import { format, parseISO } from 'date-fns';
import { format, parseISO, isValid } from 'date-fns';
import { toast } from 'react-toastify';
import { Button, Input, Card, Loading } from '../../components/common';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { archiveService } from '../../services/archive.service';
import { useNavigate } from 'react-router-dom';
// import { useNavigate } from 'react-router-dom';
export const ArchivesPage: React.FC = () => {
const [searchTerm, setSearchTerm] = useState('');
const [filterType, setFilterType] = useState<string>('all');
const [sortBy, setSortBy] = useState<'date' | 'size' | 'name'>('date');
const [currentPage, setCurrentPage] = useState(1);
const navigate = useNavigate();
// const navigate = useNavigate();
const queryClient = useQueryClient();
// Helper function to safely format dates
const formatDate = (dateString: string | null | undefined, formatStr: string): string => {
if (!dateString) return '';
try {
const date = parseISO(dateString);
return isValid(date) ? format(date, formatStr) : '';
} catch {
return '';
}
};
// Fetch archives from API
const { data: archivesData, isLoading } = useQuery({
queryKey: ['admin-archives', currentPage],
@@ -54,7 +64,9 @@ export const ArchivesPage: React.FC = () => {
return b.archiveSize - a.archiveSize;
case 'date':
default:
return new Date(b.archivedAt).getTime() - new Date(a.archivedAt).getTime();
const dateA = a.archivedAt ? new Date(a.archivedAt).getTime() : 0;
const dateB = b.archivedAt ? new Date(b.archivedAt).getTime() : 0;
return dateB - dateA;
}
});
@@ -107,9 +119,10 @@ export const ArchivesPage: React.FC = () => {
}
};
const handleViewDetails = (archive: typeof archives[0]) => {
navigate(`/admin/archives/${archive.id}`);
};
// Details view not implemented yet
// const handleViewDetails = (archive: typeof archives[0]) => {
// navigate(`/admin/archives/${archive.id}`);
// };
if (isLoading) {
return (
@@ -257,7 +270,7 @@ export const ArchivesPage: React.FC = () => {
<div>
<p className="text-sm font-medium text-neutral-900">{archive.eventName}</p>
<p className="text-xs text-neutral-500">
Event date: {format(parseISO(archive.eventDate), 'MMM d, yyyy')}
Event date: {formatDate(archive.eventDate, 'MMM d, yyyy') || 'N/A'}
</p>
</div>
</td>
@@ -266,9 +279,9 @@ export const ArchivesPage: React.FC = () => {
</td>
<td className="px-6 py-4 text-sm text-neutral-700">
<div>
<p>{format(parseISO(archive.archivedAt), 'MMM d, yyyy')}</p>
<p>{formatDate(archive.archivedAt, 'MMM d, yyyy') || 'Processing...'}</p>
<p className="text-xs text-neutral-500">
{format(parseISO(archive.archivedAt), 'h:mm a')}
{formatDate(archive.archivedAt, 'h:mm a')}
</p>
</div>
</td>
@@ -280,6 +293,7 @@ export const ArchivesPage: React.FC = () => {
</td>
<td className="px-6 py-4 text-right">
<div className="flex items-center justify-end gap-2">
{/* Details view not implemented yet
<Button
variant="ghost"
size="sm"
@@ -288,6 +302,7 @@ export const ArchivesPage: React.FC = () => {
>
Details
</Button>
*/}
<Button
variant="ghost"
size="sm"