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:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user