mitai-jinkendo/frontend/src/components/PromptGenerator.jsx

191 lines
6.5 KiB
React
Raw Normal View History

import { useState } from 'react'
import { api } from '../utils/api'
export default function PromptGenerator({ onGenerated, onClose }) {
const [goal, setGoal] = useState('')
const [dataCategories, setDataCategories] = useState(['körper', 'ernährung'])
const [exampleOutput, setExampleOutput] = useState('')
const [exampleData, setExampleData] = useState(null)
const [generating, setGenerating] = useState(false)
const [loadingExample, setLoadingExample] = useState(false)
const categories = [
{ id: 'körper', label: 'Körper (Gewicht, KF, Umfänge)' },
{ id: 'ernährung', label: 'Ernährung (Kalorien, Makros)' },
{ id: 'training', label: 'Training (Volumen, Typen)' },
{ id: 'schlaf', label: 'Schlaf (Dauer, Qualität)' },
{ id: 'vitalwerte', label: 'Vitalwerte (RHR, HRV, VO2max)' },
{ id: 'ziele', label: 'Ziele (Fortschritt, Prognose)' }
]
const handleToggleCategory = (catId) => {
if (dataCategories.includes(catId)) {
setDataCategories(dataCategories.filter(c => c !== catId))
} else {
setDataCategories([...dataCategories, catId])
}
}
const handleShowExampleData = async () => {
try {
setLoadingExample(true)
const placeholders = await api.listPlaceholders()
setExampleData(placeholders)
} catch (e) {
alert('Fehler: ' + e.message)
} finally {
setLoadingExample(false)
}
}
const handleGenerate = async () => {
if (!goal.trim()) {
alert('Bitte Ziel beschreiben')
return
}
if (dataCategories.length === 0) {
alert('Bitte mindestens einen Datenbereich wählen')
return
}
try {
setGenerating(true)
const result = await api.generatePrompt({
goal,
data_categories: dataCategories,
example_output: exampleOutput || null
})
onGenerated(result)
} catch (e) {
alert('Fehler beim Generieren: ' + e.message)
} finally {
setGenerating(false)
}
}
return (
<div style={{
position:'fixed', inset:0, background:'rgba(0,0,0,0.6)',
display:'flex', alignItems:'center', justifyContent:'center',
zIndex:1001, padding:20
}}>
<div style={{
background:'var(--bg)', borderRadius:12, maxWidth:700, width:'100%',
maxHeight:'90vh', overflow:'auto', padding:24
}}>
<h2 style={{margin:'0 0 24px 0', fontSize:18, fontWeight:600}}>
🤖 KI-Prompt generieren
</h2>
{/* Step 1: Goal */}
<div style={{marginBottom:24}}>
<label className="form-label" style={{display:'block', marginBottom:6}}>
1️⃣ Was möchtest du analysieren?
</label>
<textarea
className="form-input"
value={goal}
onChange={e => setGoal(e.target.value)}
rows={3}
placeholder="Beispiel: Ich möchte wissen ob meine Proteinzufuhr ausreichend ist für Muskelaufbau und wie ich sie optimieren kann."
style={{width:'100%', textAlign:'left', resize:'vertical'}}
/>
</div>
{/* Step 2: Data Categories */}
<div style={{marginBottom:24}}>
<label className="form-label">
2️⃣ Welche Daten sollen analysiert werden?
</label>
<div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:8}}>
{categories.map(cat => (
<label
key={cat.id}
style={{
display:'flex', alignItems:'center', gap:8,
padding:8, background:'var(--surface)', borderRadius:6,
cursor:'pointer', fontSize:13
}}
>
<input
type="checkbox"
checked={dataCategories.includes(cat.id)}
onChange={() => handleToggleCategory(cat.id)}
/>
{cat.label}
</label>
))}
</div>
<button
onClick={handleShowExampleData}
disabled={loadingExample}
style={{
marginTop:12, fontSize:12, padding:'6px 12px',
background:'var(--surface2)', border:'1px solid var(--border)',
borderRadius:6, cursor:'pointer'
}}
>
{loadingExample ? 'Lädt...' : '📊 Beispieldaten anzeigen'}
</button>
</div>
{/* Example Data */}
{exampleData && (
<div style={{
marginBottom:24, padding:12, background:'var(--surface2)',
borderRadius:8, fontSize:11, fontFamily:'monospace',
maxHeight:200, overflow:'auto'
}}>
<strong style={{fontFamily:'var(--font)'}}>Deine aktuellen Daten:</strong>
<pre style={{marginTop:8, whiteSpace:'pre-wrap'}}>
{JSON.stringify(exampleData, null, 2)}
</pre>
</div>
)}
{/* Step 3: Desired Format */}
<div style={{marginBottom:24}}>
<label className="form-label" style={{display:'block', marginBottom:6}}>
3️⃣ Gewünschtes Antwort-Format (optional)
</label>
<textarea
className="form-input"
value={exampleOutput}
onChange={e => setExampleOutput(e.target.value)}
rows={4}
placeholder={'Beispiel:\n## Analyse\n[Bewertung]\n\n## Empfehlungen\n- Punkt 1\n- Punkt 2'}
style={{width:'100%', textAlign:'left', fontFamily:'monospace', fontSize:12, resize:'vertical'}}
/>
</div>
{/* Info Box */}
<div style={{
marginBottom:24, padding:12, background:'var(--surface)',
border:'1px solid var(--border)', borderRadius:8, fontSize:12,
color:'var(--text3)'
}}>
<strong style={{color:'var(--text2)'}}>💡 Tipp:</strong> Je präziser deine Zielbeschreibung,
desto besser der generierte Prompt. Die KI wählt automatisch passende Platzhalter
und strukturiert die Analyse optimal.
</div>
{/* Actions */}
<div style={{display:'flex', gap:12}}>
<button
className="btn btn-primary"
onClick={handleGenerate}
disabled={generating || !goal.trim() || dataCategories.length === 0}
style={{flex:1}}
>
{generating ? '⏳ Generiere...' : '🚀 Prompt generieren'}
</button>
<button className="btn" onClick={onClose}>
Abbrechen
</button>
</div>
</div>
</div>
)
}