import React, { useState, useEffect } from 'react'; import { Icons } from '../components/IconSet'; import { authService } from '../services/AuthService'; interface AdminPageProps { onBack: () => void; } const EditNpcCitizenCard: React.FC<{ citizen: any; onUpdate: () => void; onError: (error: string) => void }> = ({ citizen, onUpdate, onError }) => { const [isEditing, setIsEditing] = useState(false); const [formData, setFormData] = useState({ username: citizen.username, tags: citizen.tags.join(', '), role: citizen.stats.role, organizationId: citizen.stats.organizationId || '', storyMarkdown: citizen.storyMarkdown || '' }); const [loading, setLoading] = useState(false); const handleSave = async () => { try { setLoading(true); const response = await fetch(`https://vollidioten.ceraticsoft.de/api/players/${citizen.uuid}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ tags: formData.tags.split(',').map(tag => tag.trim()).filter(tag => tag.length > 0), organizationId: formData.organizationId || null, storyMarkdown: formData.storyMarkdown.trim() || null }) }); if (response.ok) { setIsEditing(false); onUpdate(); } else { const errorData = await response.json(); onError(errorData.error || response.json()); } } catch (err) { console.error('Error updating NPC citizen:', err); onError('Netzwerkfehler'); } finally { setLoading(false); } }; if (isEditing) { return (
{citizen.username} bearbeiten
setFormData({...formData, tags: e.target.value})} className="w-full bg-[#0b0b0d] border border-border rounded p-2 text-xs" placeholder="#Bürger, #Händler" />
); } return (
NPC

{citizen.username}

{citizen.stats.role}

Level {citizen.stats.level} • {citizen.stats.playtimeHours}h Spielzeit
Tags: {citizen.tags.join(', ') || 'Keine'}
); }; const ShopManagementModal: React.FC<{ isOpen: boolean; onClose: () => void; shopItems: any[]; onUpdate: (items: any[]) => void; projectId: string; onError: (error: string) => void; }> = ({ isOpen, onClose, shopItems, onUpdate, projectId, onError }) => { const [localItems, setLocalItems] = useState(shopItems || []); const [editingItem, setEditingItem] = useState(null); const [isAdding, setIsAdding] = useState(false); const [loading, setLoading] = useState(false); const resetForm = () => { setEditingItem(null); setIsAdding(false); }; const handleSaveItem = async (itemData: any) => { try { setLoading(true); let updatedItems = [...localItems]; if (editingItem) { // Update existing item const response = await fetch(`https://vollidioten.ceraticsoft.de/api/projects/${projectId}/shop/${editingItem.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify(itemData) }); if (response.ok) { const index = updatedItems.findIndex(item => item.id === editingItem.id); if (index !== -1) { updatedItems[index] = itemData; } } else { throw new Error('Fehler beim Aktualisieren'); } } else { // Add new item const response = await fetch(`https://vollidioten.ceraticsoft.de/api/projects/${projectId}/shop`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify(itemData) }); if (response.ok) { const newItem = await response.json(); updatedItems.push(newItem.item); } else { throw new Error('Fehler beim Hinzufügen'); } } setLocalItems(updatedItems); onUpdate(updatedItems); resetForm(); } catch (err) { console.error('Error saving shop item:', err); onError('Fehler beim Speichern des Artikels'); } finally { setLoading(false); } }; const handleDeleteItem = async (itemId: string) => { if (!confirm('Artikel wirklich löschen?')) return; try { setLoading(true); const response = await fetch(`https://vollidioten.ceraticsoft.de/api/projects/${projectId}/shop/${itemId}`, { method: 'DELETE', credentials: 'include' }); if (response.ok) { const updatedItems = localItems.filter(item => item.id !== itemId); setLocalItems(updatedItems); onUpdate(updatedItems); } else { throw new Error('Fehler beim Löschen'); } } catch (err) { console.error('Error deleting shop item:', err); onError('Fehler beim Löschen des Artikels'); } finally { setLoading(false); } }; if (!isOpen) return null; return (

Shop-Verwaltung

Shop-Artikel ({localItems.length})

Verwalte die Produkte dieses Shops

{localItems.length === 0 ? (

Noch keine Artikel im Shop.

) : (
{localItems.map((item) => (

{item.name}

{item.description}

{item.price} {item.currency} Lager: {item.stock}
))}
)} {(editingItem || isAdding) && ( )}
); }; const ShopItemForm: React.FC<{ item?: any; onSave: (itemData: any) => void; onCancel: () => void; loading: boolean; }> = ({ item, onSave, onCancel, loading }) => { const [formData, setFormData] = useState({ name: item?.name || '', description: item?.description || '', price: item?.price || '', currency: item?.currency || 'Gold', stock: item?.stock || '', type: item?.type || 'item' }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onSave({ ...formData, price: parseFloat(formData.price), stock: parseInt(formData.stock), id: item?.id // Keep existing ID for updates }); }; return (

{item ? 'Artikel bearbeiten' : 'Neuer Artikel'}

setFormData({...formData, name: e.target.value})} className="w-full bg-[#0b0b0d] border border-border rounded p-2 text-sm" required />
setFormData({...formData, price: e.target.value})} className="w-full bg-[#0b0b0d] border border-border rounded p-2 text-sm" required />
setFormData({...formData, stock: e.target.value})} className="w-full bg-[#0b0b0d] border border-border rounded p-2 text-sm" required />