'use client'; import { useState, useEffect, useRef } from 'react'; import { useLanguage } from '@/context/LanguageContext'; import { mediaApi, Media } from '@/lib/api'; import Card from '@/components/ui/Card'; import Button from '@/components/ui/Button'; import { PhotoIcon, TrashIcon, ArrowUpTrayIcon, XMarkIcon, MagnifyingGlassIcon, LinkIcon, CheckIcon, } from '@heroicons/react/24/outline'; import toast from 'react-hot-toast'; export default function AdminGalleryPage() { const { locale } = useLanguage(); const [media, setMedia] = useState([]); const [loading, setLoading] = useState(true); const [uploading, setUploading] = useState(false); const [selectedImage, setSelectedImage] = useState(null); const [filter, setFilter] = useState(''); const [copiedId, setCopiedId] = useState(null); const fileInputRef = useRef(null); useEffect(() => { loadMedia(); }, [filter]); const loadMedia = async () => { try { // We need to call the media API - let's add it if it doesn't exist const res = await fetch('/api/media', { headers: { 'Authorization': `Bearer ${localStorage.getItem('spanglish-token')}`, }, }); if (res.ok) { const data = await res.json(); setMedia(data.media || []); } } catch (error) { toast.error('Failed to load media'); } finally { setLoading(false); } }; const handleUpload = async (e: React.ChangeEvent) => { const files = e.target.files; if (!files || files.length === 0) return; setUploading(true); let successCount = 0; let failCount = 0; for (const file of Array.from(files)) { try { await mediaApi.upload(file, undefined, 'gallery'); successCount++; } catch (error) { failCount++; } } if (successCount > 0) { toast.success(`${successCount} image(s) uploaded successfully`); } if (failCount > 0) { toast.error(`${failCount} image(s) failed to upload`); } loadMedia(); setUploading(false); if (fileInputRef.current) { fileInputRef.current.value = ''; } }; const handleDelete = async (id: string) => { if (!confirm('Are you sure you want to delete this image?')) return; try { await mediaApi.delete(id); toast.success('Image deleted'); loadMedia(); if (selectedImage?.id === id) { setSelectedImage(null); } } catch (error) { toast.error('Failed to delete image'); } }; const copyUrl = async (url: string, id: string) => { const fullUrl = window.location.origin + url; try { await navigator.clipboard.writeText(fullUrl); setCopiedId(id); toast.success('URL copied'); setTimeout(() => setCopiedId(null), 2000); } catch (error) { toast.error('Failed to copy URL'); } }; const formatDate = (dateStr: string) => { return new Date(dateStr).toLocaleDateString(locale === 'es' ? 'es-ES' : 'en-US', { year: 'numeric', month: 'short', day: 'numeric', }); }; const filteredMedia = media.filter(m => { if (!filter) return true; if (filter === 'gallery') return m.relatedType === 'gallery' || !m.relatedType; if (filter === 'event') return m.relatedType === 'event'; return true; }); if (loading) { return (
); } return (

Gallery Management

{/* Stats */}

{media.length}

Total Images

{media.filter(m => m.relatedType === 'event').length}

Event Images

{media.filter(m => m.relatedType === 'gallery' || !m.relatedType).length}

Gallery Images

{/* Filter */}
{/* Gallery Grid */} {filteredMedia.length === 0 ? (

No images yet

Upload images to build your gallery

) : (
{filteredMedia.map((item) => ( setSelectedImage(item)} />
{item.relatedType && (
{item.relatedType === 'event' ? 'Event' : 'Gallery'}
)}
))}
)} {/* Image Preview Modal */} {selectedImage && (
setSelectedImage(null)} >
e.stopPropagation()} >

Uploaded: {formatDate(selectedImage.createdAt)}

)}
); }