diff --git a/frontend/src/pages/Analysis.jsx b/frontend/src/pages/Analysis.jsx index 27377be..4c55d33 100644 --- a/frontend/src/pages/Analysis.jsx +++ b/frontend/src/pages/Analysis.jsx @@ -179,6 +179,10 @@ export default function Analysis() { const activePrompts = prompts.filter(p=>p.active && !p.slug.startsWith('pipeline_')) + // Pipeline is available only if ALL pipeline sub-prompts are active + const pipelineSlugs = ['pipeline_body','pipeline_nutrition','pipeline_activity','pipeline_synthesis','pipeline_goals'] + const pipelineAvailable = pipelineSlugs.every(slug => prompts.find(p=>p.slug===slug)?.active) + return (

KI-Analyse

@@ -221,36 +225,38 @@ export default function Analysis() {
)} - {/* Pipeline button */} -
-
-
-
πŸ”¬ Mehrstufige Gesamtanalyse
-
- 3 spezialisierte KI-Calls parallel (KΓΆrper + ErnΓ€hrung + AktivitΓ€t), - dann Synthese + Zielabgleich. Detaillierteste Auswertung. -
- {allInsights.find(i=>i.scope==='pipeline') && ( -
- Letzte Analyse: {dayjs(allInsights.find(i=>i.scope==='pipeline').created).format('DD.MM.YYYY, HH:mm')} + {/* Pipeline button - only if all sub-prompts are active */} + {pipelineAvailable && ( +
+
+
+
πŸ”¬ Mehrstufige Gesamtanalyse
+
+ 3 spezialisierte KI-Calls parallel (KΓΆrper + ErnΓ€hrung + AktivitΓ€t), + dann Synthese + Zielabgleich. Detaillierteste Auswertung.
- )} + {allInsights.find(i=>i.scope==='pipeline') && ( +
+ Letzte Analyse: {dayjs(allInsights.find(i=>i.scope==='pipeline').created).format('DD.MM.YYYY, HH:mm')} +
+ )} +
+ + {!canUseAI &&
πŸ”’ KI nicht freigeschaltet
}
- - {!canUseAI &&
πŸ”’ KI nicht freigeschaltet
} + {pipelineLoading && ( +
+ ⚑ Stufe 1: 3 parallele Analyse-Calls… dann Synthese… dann Zielabgleich +
+ )}
- {pipelineLoading && ( -
- ⚑ Stufe 1: 3 parallele Analyse-Calls… dann Synthese… dann Zielabgleich -
- )} -
+ )} {!canUseAI && (
)} -
) } // ── Nutrition Section ───────────────────────────────────────────────────────── -function NutritionSection({ nutrition, weights, profile, insights, onRequest, loadingSlug }) { +function NutritionSection({ nutrition, weights, profile, insights, onRequest, loadingSlug, filterActiveSlugs }) { const [period, setPeriod] = useState(30) if (!nutrition?.length) return ( @@ -579,13 +579,13 @@ function NutritionSection({ nutrition, weights, profile, insights, onRequest, lo
BEWERTUNG
{macroRules.map((item,i)=>)}
- +
) } // ── Activity Section ────────────────────────────────────────────────────────── -function ActivitySection({ activities, insights, onRequest, loadingSlug }) { +function ActivitySection({ activities, insights, onRequest, loadingSlug, filterActiveSlugs }) { const [period, setPeriod] = useState(30) if (!activities?.length) return ( @@ -657,13 +657,13 @@ function ActivitySection({ activities, insights, onRequest, loadingSlug }) {
BEWERTUNG
{actRules.map((item,i)=>)}
- + ) } // ── Correlation Section ─────────────────────────────────────────────────────── -function CorrelationSection({ corrData, insights, profile, onRequest, loadingSlug }) { +function CorrelationSection({ corrData, insights, profile, onRequest, loadingSlug, filterActiveSlugs }) { const filtered = (corrData||[]).filter(d=>d.kcal&&d.weight) if (filtered.length < 5) return ( @@ -852,7 +852,7 @@ function CorrelationSection({ corrData, insights, profile, onRequest, loadingSlu )} - + ) } @@ -903,6 +903,7 @@ export default function History() { const [activities, setActivities] = useState([]) const [corrData, setCorrData] = useState([]) const [insights, setInsights] = useState([]) + const [prompts, setPrompts] = useState([]) const [profile, setProfile] = useState(null) const [loading, setLoading] = useState(true) const [loadingSlug,setLoadingSlug]= useState(null) @@ -911,10 +912,12 @@ export default function History() { api.listWeight(365), api.listCaliper(), api.listCirc(), api.listNutrition(90), api.listActivity(200), api.nutritionCorrelations(), api.latestInsights(), api.getProfile(), - ]).then(([w,ca,ci,n,a,corr,ins,p])=>{ + api.listPrompts(), + ]).then(([w,ca,ci,n,a,corr,ins,p,pr])=>{ setWeights(w); setCalipers(ca); setCircs(ci) setNutrition(n); setActivities(a); setCorrData(corr) setInsights(Array.isArray(ins)?ins:[]); setProfile(p) + setPrompts(Array.isArray(pr)?pr:[]) setLoading(false) }) @@ -923,17 +926,23 @@ export default function History() { const requestInsight = async (slug) => { setLoadingSlug(slug) try { - const pid=localStorage.getItem('bodytrack_active_profile')||'' - const r=await api.runInsight(slug) - if(!r.ok) throw new Error(await r.text()) - const ins=await api.latestInsights() + const result = await api.runInsight(slug) + // result is already JSON, not a Response object + const ins = await api.latestInsights() setInsights(Array.isArray(ins)?ins:[]) - } catch(e){ alert('KI-Fehler: '+e.message) } + } catch(e){ + alert('KI-Fehler: '+e.message) + } finally{ setLoadingSlug(null) } } if(loading) return
- const sp={insights,onRequest:requestInsight,loadingSlug} + + // Filter active prompts + const activeSlugs = prompts.filter(p=>p.active).map(p=>p.slug) + const filterActiveSlugs = (slugs) => slugs.filter(s=>activeSlugs.includes(s)) + + const sp={insights,onRequest:requestInsight,loadingSlug,filterActiveSlugs} return (