'use client' import React, { useEffect, useState, useCallback } from 'react' import Link from 'next/link' import { useParams } from 'next/navigation' interface AgentDetail { id: string name: string description: string color: string icon: string status: 'active' | 'inactive' | 'error' version: string soulContent: string createdAt: string | null updatedAt: string | null fileSize: number stats: { sessionsToday: number avgResponseTime: string successRate: string } } interface BackupEntry { filename: string timestamp: number size: number } function StatusBadge({ status }: { status: string }) { const colors = { active: 'bg-green-100 text-green-700', inactive: 'bg-gray-100 text-gray-600', error: 'bg-red-100 text-red-700', } const labels = { active: 'Aktiv', inactive: 'Inaktiv', error: 'Fehler' } return ( {labels[status as keyof typeof labels] || status} ) } export default function AgentDetailPage() { const params = useParams() const agentId = params.agentId as string const [agent, setAgent] = useState(null) const [loading, setLoading] = useState(true) const [activeTab, setActiveTab] = useState<'soul' | 'stats' | 'history'>('soul') const [editing, setEditing] = useState(false) const [editContent, setEditContent] = useState('') const [saving, setSaving] = useState(false) const [saveMessage, setSaveMessage] = useState('') const [backups, setBackups] = useState([]) const loadAgent = useCallback(async () => { try { const res = await fetch(`/api/sdk/agents/${agentId}`) if (res.ok) { const data = await res.json() setAgent(data) if (!editing) setEditContent(data.soulContent) } } catch (err) { console.error('Failed to load agent:', err) } finally { setLoading(false) } }, [agentId, editing]) const loadBackups = useCallback(async () => { try { const res = await fetch(`/api/sdk/agents/${agentId}/soul?history=true`) if (res.ok) { const data = await res.json() setBackups(data.backups || []) } } catch (err) { console.error('Failed to load backups:', err) } }, [agentId]) useEffect(() => { loadAgent() }, [loadAgent]) useEffect(() => { if (activeTab === 'history') loadBackups() }, [activeTab, loadBackups]) const handleSave = async () => { setSaving(true) setSaveMessage('') try { const res = await fetch(`/api/sdk/agents/${agentId}/soul`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: editContent }), }) if (res.ok) { setSaveMessage('SOUL-Datei gespeichert') setEditing(false) await loadAgent() } else { const err = await res.json() setSaveMessage(`Fehler: ${err.error}`) } } catch { setSaveMessage('Speichern fehlgeschlagen') } finally { setSaving(false) setTimeout(() => setSaveMessage(''), 3000) } } const handleReset = () => { if (agent) { setEditContent(agent.soulContent) setEditing(false) } } if (loading) { return ( ) } if (!agent) { return ( Agent nicht gefunden. Zurueck zur Uebersicht ) } return ( {/* Header */} {agent.icon === 'shield' ? ( ) : ( )} {agent.name} {agent.description} {/* Stats Bar */} {agent.stats.sessionsToday} Sessions heute {agent.stats.avgResponseTime} Avg. Antwortzeit {agent.stats.successRate} Erfolgsrate v{agent.version} Version {agent.fileSize ? `${(agent.fileSize / 1024).toFixed(1)}k` : '—'} SOUL-Groesse {/* Tabs */} {[ { id: 'soul' as const, label: 'SOUL-File' }, { id: 'stats' as const, label: 'Live-Statistiken' }, { id: 'history' as const, label: 'Aenderungshistorie' }, ].map(tab => ( setActiveTab(tab.id)} className={`px-4 py-3 text-sm font-medium border-b-2 transition-colors ${ activeTab === tab.id ? 'border-purple-600 text-purple-700' : 'border-transparent text-gray-500 hover:text-gray-700' }`} > {tab.label} ))} {/* Tab Content */} {activeTab === 'soul' && ( {/* Toolbar */} {agent.updatedAt && `Zuletzt geaendert: ${new Date(agent.updatedAt).toLocaleString('de-DE')}`} {saveMessage && ( {saveMessage} )} {editing ? ( <> Abbrechen {saving ? 'Speichern...' : 'Speichern'} > ) : ( setEditing(true)} className="px-3 py-1.5 text-sm text-purple-600 bg-purple-50 border border-purple-200 rounded-lg hover:bg-purple-100" > Bearbeiten )} {/* Editor */} setEditContent(e.target.value)} readOnly={!editing} className={`w-full h-[600px] font-mono text-sm p-4 border rounded-xl resize-none focus:outline-none ${ editing ? 'border-purple-300 bg-white focus:ring-2 focus:ring-purple-200' : 'border-gray-200 bg-gray-50 cursor-default' }`} spellCheck={false} /> )} {activeTab === 'stats' && ( Live-Statistiken Detaillierte Echtzeit-Statistiken werden in einer zukuenftigen Version implementiert. )} {activeTab === 'history' && ( {backups.length === 0 ? ( Keine Backups vorhanden Backups werden automatisch beim Speichern von SOUL-Dateien erstellt. ) : ( {backups.map((backup) => ( {new Date(backup.timestamp).toLocaleString('de-DE')} {(backup.size / 1024).toFixed(1)} KB — {backup.filename} Backup ))} )} )} ) }
Agent nicht gefunden.
{agent.description}
Detaillierte Echtzeit-Statistiken werden in einer zukuenftigen Version implementiert.
Backups werden automatisch beim Speichern von SOUL-Dateien erstellt.