import { useState, useEffect } from 'react' import { api } from '../utils/api' import UnifiedPromptModal from '../components/UnifiedPromptModal' import { Star, Trash2, Edit, Copy, Filter } from 'lucide-react' /** * Admin Prompts Page - Unified System (Issue #28 Phase 3) * * Manages both base and pipeline-type prompts in one interface. */ export default function AdminPromptsPage() { const [prompts, setPrompts] = useState([]) const [filteredPrompts, setFilteredPrompts] = useState([]) const [typeFilter, setTypeFilter] = useState('all') // 'all' | 'base' | 'pipeline' const [category, setCategory] = useState('all') const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [editingPrompt, setEditingPrompt] = useState(null) const [showNewPrompt, setShowNewPrompt] = useState(false) const categories = [ { id: 'all', label: 'Alle Kategorien' }, { id: 'körper', label: 'Körper' }, { id: 'ernährung', label: 'Ernährung' }, { id: 'training', label: 'Training' }, { id: 'schlaf', label: 'Schlaf' }, { id: 'vitalwerte', label: 'Vitalwerte' }, { id: 'ziele', label: 'Ziele' }, { id: 'ganzheitlich', label: 'Ganzheitlich' }, { id: 'pipeline', label: 'Pipeline' } ] useEffect(() => { loadPrompts() }, []) useEffect(() => { let filtered = prompts // Filter by type if (typeFilter === 'base') { filtered = filtered.filter(p => p.type === 'base') } else if (typeFilter === 'pipeline') { filtered = filtered.filter(p => p.type === 'pipeline') } // Filter by category if (category !== 'all') { filtered = filtered.filter(p => p.category === category) } setFilteredPrompts(filtered) }, [typeFilter, category, prompts]) const loadPrompts = async () => { try { setLoading(true) const data = await api.listAdminPrompts() setPrompts(data) setError(null) } catch (e) { setError(e.message) } finally { setLoading(false) } } const handleToggleActive = async (prompt) => { try { await api.updateUnifiedPrompt(prompt.id, { active: !prompt.active }) await loadPrompts() } catch (e) { alert('Fehler: ' + e.message) } } const handleDelete = async (prompt) => { if (!confirm(`Prompt "${prompt.name}" wirklich löschen?`)) return try { await api.deletePrompt(prompt.id) await loadPrompts() } catch (e) { alert('Fehler: ' + e.message) } } const handleDuplicate = async (prompt) => { try { await api.duplicatePrompt(prompt.id) await loadPrompts() } catch (e) { alert('Fehler: ' + e.message) } } const handleSave = async () => { setEditingPrompt(null) setShowNewPrompt(false) await loadPrompts() } const getStageCount = (prompt) => { if (prompt.type !== 'pipeline' || !prompt.stages) return 0 try { const stages = typeof prompt.stages === 'string' ? JSON.parse(prompt.stages) : prompt.stages return stages.length } catch (e) { return 0 } } const getTypeLabel = (type) => { if (type === 'base') return 'Basis' if (type === 'pipeline') return 'Pipeline' return type || 'Pipeline' // Default for old prompts } const getTypeColor = (type) => { if (type === 'base') return 'var(--accent)' if (type === 'pipeline') return '#6366f1' return 'var(--text3)' } return (

KI-Prompts ({filteredPrompts.length})

{error && (
{error}
)} {/* Filters */}
Typ:
{/* Prompts Table */} {loading ? (
Lädt...
) : (
{filteredPrompts.length === 0 ? ( ) : ( filteredPrompts.map(prompt => ( )) )}
Typ Name Kategorie Stages Status Aktionen
Keine Prompts gefunden
{getTypeLabel(prompt.type)}
{prompt.display_name || prompt.name}
{prompt.slug}
{prompt.category || 'ganzheitlich'} {prompt.type === 'pipeline' ? ( {getStageCount(prompt)} Stages ) : ( — )}
)} {/* Unified Prompt Modal */} {(editingPrompt || showNewPrompt) && ( { setEditingPrompt(null) setShowNewPrompt(false) }} /> )}
) }