From 848ba0a815221dca01052ccf8edad054aaa50bca Mon Sep 17 00:00:00 2001 From: Lars Date: Mon, 23 Mar 2026 22:04:29 +0100 Subject: [PATCH] refactor: mehrstufiger Quality-Filter statt Toggle (#24) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Statt einfachem On/Off Toggle jetzt 4 Qualitätsstufen: - 📊 Alle (kein Filter) - ✓ Hochwertig (excellent + good + acceptable) - ✓✓ Sehr gut (excellent + good) - ⭐ Exzellent (nur excellent) UI: - Button-Group (Segmented Control) mit 4 Stufen - Beschreibung welche Labels inkludiert werden - Anzeige: X von Y Aktivitäten (wenn gefiltert) User-Feedback: Stufenweiser Filter ist flexibler als binärer Toggle Co-Authored-By: Claude Opus 4.6 --- frontend/src/pages/History.jsx | 60 ++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/frontend/src/pages/History.jsx b/frontend/src/pages/History.jsx index f7e4447..22c966a 100644 --- a/frontend/src/pages/History.jsx +++ b/frontend/src/pages/History.jsx @@ -588,16 +588,22 @@ function NutritionSection({ nutrition, weights, profile, insights, onRequest, lo // ── Activity Section ────────────────────────────────────────────────────────── function ActivitySection({ activities, insights, onRequest, loadingSlug, filterActiveSlugs }) { const [period, setPeriod] = useState(30) - const [qualityFilter, setQualityFilter] = useState(false) // Issue #24: Quality-Filter Toggle + const [qualityLevel, setQualityLevel] = useState('all') // Issue #24: Quality-Filter (all, quality, very_good, excellent) if (!activities?.length) return ( ) const cutoff = dayjs().subtract(period,'day').format('YYYY-MM-DD') - // Issue #24: Filter nach Datum UND Quality-Label - const filtA = activities.filter(d => - (period===9999 || d.date>=cutoff) && - (!qualityFilter || ['excellent', 'good', 'acceptable'].includes(d.quality_label)) - ) + + // Issue #24: Mehrstufiger Quality-Filter + const filtA = activities.filter(d => { + if (period !== 9999 && d.date < cutoff) return false + + if (qualityLevel === 'all') return true + if (qualityLevel === 'quality') return ['excellent', 'good', 'acceptable'].includes(d.quality_label) + if (qualityLevel === 'very_good') return ['excellent', 'good'].includes(d.quality_label) + if (qualityLevel === 'excellent') return d.quality_label === 'excellent' + return true + }) const byDate={} filtA.forEach(a=>{ byDate[a.date]=(byDate[a.date]||0)+(a.kcal_active||0) }) @@ -626,20 +632,34 @@ function ActivitySection({ activities, insights, onRequest, loadingSlug, filterA - {/* Issue #24: Quality-Filter Toggle */} -
- - {qualityFilter && ( - - ({filtA.length} von {activities.filter(d=>period===9999||d.date>=cutoff).length}) - + {/* Issue #24: Mehrstufiger Quality-Filter */} +
+
QUALITÄTSFILTER
+
+ {[ + {v:'all', l:'Alle', icon:'📊'}, + {v:'quality', l:'Hochwertig', icon:'✓'}, + {v:'very_good', l:'Sehr gut', icon:'✓✓'}, + {v:'excellent', l:'Exzellent', icon:'⭐'} + ].map(o => ( + + ))} +
+ {qualityLevel !== 'all' && ( +
+ {filtA.length} von {activities.filter(d=>period===9999||d.date>=cutoff).length} Aktivitäten + {qualityLevel === 'quality' && ' (excellent, good, acceptable)'} + {qualityLevel === 'very_good' && ' (excellent, good)'} + {qualityLevel === 'excellent' && ' (nur excellent)'} +
)}