'use client' import { useState, useEffect, useCallback } from 'react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from '@/components/ui/dialog' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { useToast } from '@/components/ui/use-toast' import { Upload, Pencil, Trash2, Eye, EyeOff, Image as ImageIcon, Loader2 } from 'lucide-react' import { ICON_TYPES, type IconAsset, type IconCategory } from './admin-constants' export function IconsTab() { const { toast } = useToast() const [icons, setIcons] = useState([]) const [categories, setCategories] = useState([]) const [selectedCategory, setSelectedCategory] = useState('all') const [isUploadDialogOpen, setIsUploadDialogOpen] = useState(false) const [uploadFiles, setUploadFiles] = useState(null) const [uploadCategory, setUploadCategory] = useState('') const [uploadIconType, setUploadIconType] = useState('STANDARD') const [uploadIconName, setUploadIconName] = useState('') const [isUploading, setIsUploading] = useState(false) const [isEditDialogOpen, setIsEditDialogOpen] = useState(false) const [editingIcon, setEditingIcon] = useState(null) const [editIconName, setEditIconName] = useState('') const [editIconCategory, setEditIconCategory] = useState('') const [editIconType, setEditIconType] = useState('STANDARD') const [editIconTags, setEditIconTags] = useState('') const fetchData = useCallback(async () => { try { const [iconRes, catRes] = await Promise.all([ fetch('/api/admin/icons'), fetch('/api/admin/categories'), ]) if (iconRes.ok) setIcons((await iconRes.json()).icons || []) if (catRes.ok) setCategories((await catRes.json()).categories || []) } catch (e) { console.error('Error fetching icons:', e) } }, []) useEffect(() => { fetchData() }, [fetchData]) const handleUploadIcons = async () => { if (!uploadFiles || !uploadCategory) return setIsUploading(true) try { for (const file of Array.from(uploadFiles)) { const formData = new FormData() formData.append('file', file) formData.append('categoryId', uploadCategory) formData.append('iconType', uploadIconType) formData.append('name', uploadIconName.trim() || file.name.replace(/\.(png|svg|jpg|jpeg|webp)$/i, '')) const res = await fetch('/api/admin/icons/upload', { method: 'POST', body: formData }) if (!res.ok) { const err = await res.json(); throw new Error(err.error || 'Upload fehlgeschlagen') } } toast({ title: `${uploadFiles.length} Icon(s) hochgeladen` }) setIsUploadDialogOpen(false); setUploadFiles(null); setUploadCategory(''); setUploadIconName('') fetchData() } catch (error) { toast({ title: 'Upload-Fehler', description: error instanceof Error ? error.message : 'Fehler', variant: 'destructive' }) } finally { setIsUploading(false) } } const handleEditIcon = (icon: IconAsset) => { setEditingIcon(icon); setEditIconName(icon.name); setEditIconCategory(icon.category.id) setEditIconType(icon.iconType); setEditIconTags(icon.tags?.join(', ') || '') setIsEditDialogOpen(true) } const handleSaveIcon = async () => { if (!editingIcon) return try { const res = await fetch(`/api/admin/icons/${editingIcon.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: editIconName, categoryId: editIconCategory, iconType: editIconType, tags: editIconTags.split(',').map(t => t.trim()).filter(Boolean), }), }) if (res.ok) { toast({ title: 'Icon aktualisiert' }); setIsEditDialogOpen(false); setEditingIcon(null); fetchData() } else { const err = await res.json(); throw new Error(err.error) } } catch (error) { toast({ title: 'Fehler', description: error instanceof Error ? error.message : 'Fehler', variant: 'destructive' }) } } const handleToggleIconActive = async (icon: IconAsset) => { try { const res = await fetch(`/api/admin/icons/${icon.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ isActive: !icon.isActive }), }) if (res.ok) { toast({ title: icon.isActive ? 'Symbol deaktiviert' : 'Symbol aktiviert' }); fetchData() } else { const err = await res.json(); toast({ title: 'Fehler', description: err.error, variant: 'destructive' }) } } catch { toast({ title: 'Fehler', variant: 'destructive' }) } } const handleDeleteIcon = async (id: string) => { if (!confirm('Icon wirklich löschen?')) return try { const res = await fetch(`/api/admin/icons/${id}`, { method: 'DELETE' }) if (res.ok) { toast({ title: 'Icon gelöscht' }); fetchData() } } catch { toast({ title: 'Fehler', variant: 'destructive' }) } } const filteredIcons = selectedCategory === 'all' ? icons : icons.filter(i => i.category.id === selectedCategory) return (
{filteredIcons.length} Symbol(e)
{filteredIcons.length === 0 ? (

Keine Symbole vorhanden

Laden Sie eigene Symbole hoch (PNG, SVG, JPEG)

) : (
{filteredIcons.map(icon => (
{icon.name}

{icon.name}

{icon.category.name}

{icon.isSystem &&

System

}
))}
)} {/* Upload Dialog */} Icons hochladen
setUploadFiles(e.target.files)} />
setUploadIconName(e.target.value)} placeholder="z.B. Feuerwehrauto TLF" />
{/* Edit Icon Dialog */} Icon bearbeiten
{editingIcon && (
{editingIcon.name}
)}
setEditIconName(e.target.value)} />
setEditIconTags(e.target.value)} placeholder="z.B. feuerwehr, fahrzeug" />
) }