import React, { useEffect, useState } from 'react'; import { Box, Container, Heading, Text, Table, Thead, Tbody, Tr, Th, Td, Button, HStack, VStack, Badge, Spinner, useToast, Image, Link, Alert, AlertIcon, AlertTitle, AlertDescription, useColorModeValue, } from '@chakra-ui/react'; import { RefreshCw, ExternalLink, Calendar, Image as ImageIcon, Eye } from 'lucide-react'; import AdminLayout from '../../layouts/AdminLayout'; import api from '../../services/api'; interface Album { id: string; title: string; url: string; date: string; photos_count: number; views_count?: number; photos: Array<{ id: string; page_url: string; image_1500: string; }>; } const resolveBackendUrl = (path: string) => { try { if (/^https?:\/\//i.test(path)) return path; if (path.startsWith('/cache') || path.startsWith('/uploads') || path.startsWith('/api/')) { const base = process.env.REACT_APP_API_BASE_URL || process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1'; const b = new URL(base); const abs = new URL(path, `${b.protocol}//${b.host}`); return abs.toString(); } return path; } catch { return path; } }; const GalleryAdminPage: React.FC = () => { const cardBg = useColorModeValue('white', 'gray.800'); const borderColor = useColorModeValue('gray.200', 'gray.700'); const textSecondary = useColorModeValue('gray.600', 'gray.400'); const [albums, setAlbums] = useState([]); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [error, setError] = useState(''); const toast = useToast(); const fetchAlbums = async () => { setLoading(true); setError(''); try { // Try to load from both sources and combine them (similar to frontpage) const [profileRes, albumsRes] = await Promise.allSettled([ fetch(resolveBackendUrl('/cache/prefetch/zonerama_profile.json'), { cache: 'no-cache' }), fetch(resolveBackendUrl('/cache/prefetch/zonerama_albums.json'), { cache: 'no-cache' }) ]); let combinedAlbums: Album[] = []; // Get profile albums (main source) if (profileRes.status === 'fulfilled' && profileRes.value.ok) { const profileData = await profileRes.value.json(); if (profileData.albums && Array.isArray(profileData.albums)) { combinedAlbums = [...profileData.albums]; } } // Get additional albums (fallback source) if (albumsRes.status === 'fulfilled' && albumsRes.value.ok) { const albumsData = await albumsRes.value.json(); const blogAlbums = Array.isArray(albumsData) ? albumsData : []; // Filter out empty albums and avoid duplicates const validBlogAlbums = blogAlbums.filter((album: any) => album.id && album.title && !combinedAlbums.some(existing => existing.id === album.id) ); combinedAlbums = [...combinedAlbums, ...validBlogAlbums]; } setAlbums(combinedAlbums); } catch (err: any) { setError(err.message || 'Nepodařilo se načíst alba'); } finally { setLoading(false); } }; const handleRefresh = async () => { setRefreshing(true); try { // Use the api service which automatically includes authentication await api.post('/admin/gallery/refresh'); toast({ title: 'Galerie obnovena', description: 'Data z Zonerama byla úspěšně načtena', status: 'success', duration: 3000, isClosable: true, }); // Reload albums after refresh await fetchAlbums(); } catch (err: any) { const errorMessage = err.response?.data?.error || err.message || 'Nepodařilo se obnovit galerii'; toast({ title: 'Chyba při obnově galerie', description: errorMessage, status: 'error', duration: 5000, isClosable: true, }); console.error('Gallery refresh error:', err); } finally { setRefreshing(false); } }; useEffect(() => { fetchAlbums(); }, []); const totalPhotos = albums.reduce((sum, album) => sum + album.photos_count, 0); const totalViews = albums.reduce((sum, album) => sum + (album.views_count || 0), 0); return ( {/* Header */} Správa galerie Správa alb a fotografií ze Zonerama {/* Zonerama Info */} Zonerama integrace Alba jsou automaticky načítána ze Zonerama profilu. Klikněte na "Obnovit z Zonerama" pro synchronizaci s nejnovějšími daty. {/* Statistics */} {!loading && !error && albums.length > 0 && ( {albums.length} alb {totalPhotos} fotografií {totalViews} zhlédnutí )} {/* Loading State */} {loading && ( Načítám alba... )} {/* Error State */} {error && !loading && ( {error} )} {/* Empty State */} {!loading && !error && albums.length === 0 && ( Zatím nejsou k dispozici žádná alba Klikněte na tlačítko "Obnovit z Zonerama" pro načtení alb. )} {/* Albums Table */} {!loading && !error && albums.length > 0 && ( {albums.map((album) => { const coverPhoto = album.photos && album.photos.length > 0 ? album.photos[0] : null; return ( ); })}
Náhled Název Datum Fotky Zhlédnutí Akce
{coverPhoto ? ( {album.title} ) : ( )} {album.title} {album.date} {album.photos_count} {album.views_count || 0}
)}
); }; export default GalleryAdminPage;