diff --git a/frontend/src/pages/GoalsPage.jsx b/frontend/src/pages/GoalsPage.jsx
index ca998c4..9293783 100644
--- a/frontend/src/pages/GoalsPage.jsx
+++ b/frontend/src/pages/GoalsPage.jsx
@@ -286,7 +286,7 @@ export default function GoalsPage() {
)}
- Gewichte deine Trainingsziele individuell. Die Summe muss 100% ergeben.
+ Setze relative Gewichte für deine Trainingsziele. Das System berechnet automatisch die Prozentanteile.
{focusAreas && !focusAreas.custom && (
ℹ️ Aktuell abgeleitet aus Trainingsmodus "{goalMode}" - klicke "Anpassen" für individuelle Gewichtung
@@ -305,87 +305,68 @@ export default function GoalsPage() {
{ key: 'endurance_pct', label: 'Ausdauer', icon: '🏃', color: '#1D9E75' },
{ key: 'flexibility_pct', label: 'Beweglichkeit', icon: '🤸', color: '#E67E22' },
{ key: 'health_pct', label: 'Gesundheit', icon: '❤️', color: '#F59E0B' }
- ].map(area => (
-
-
-
-
{area.icon}
-
{area.label}
+ ].map(area => {
+ const weight = Math.round(focusTemp[area.key] / 10)
+ const sum = Object.values(focusTemp).reduce((a, b) => a + b, 0)
+ const actualPercent = sum > 0 ? Math.round(focusTemp[area.key] / sum * 100) : 0
+
+ return (
+
+
+
+ {area.icon}
+ {area.label}
+
+
+ {weight} → {actualPercent}%
+
-
- {focusTemp[area.key]}%
-
+
setFocusTemp(f => ({ ...f, [area.key]: parseInt(e.target.value) * 10 }))}
+ style={{
+ width: '100%',
+ height: 8,
+ borderRadius: 4,
+ background: `linear-gradient(to right, ${area.color} 0%, ${area.color} ${weight * 10}%, var(--border) ${weight * 10}%, var(--border) 100%)`,
+ outline: 'none',
+ cursor: 'pointer'
+ }}
+ />
-
setFocusTemp(f => ({ ...f, [area.key]: parseInt(e.target.value) }))}
- style={{
- width: '100%',
- height: 8,
- borderRadius: 4,
- background: `linear-gradient(to right, ${area.color} 0%, ${area.color} ${focusTemp[area.key]}%, var(--border) ${focusTemp[area.key]}%, var(--border) 100%)`,
- outline: 'none',
- cursor: 'pointer'
- }}
- />
-
- ))}
+ )
+ })}
- {/* Sum Display */}
+ {/* Weight Total Display */}
{
- const sum = Object.values(focusTemp).reduce((a, b) => a + b, 0)
- if (sum === 100) return 'var(--accent)'
- return '#FEF2F2'
- })(),
- border: (() => {
- const sum = Object.values(focusTemp).reduce((a, b) => a + b, 0)
- if (sum === 100) return '1px solid var(--accent)'
- return '1px solid #FCA5A5'
- })(),
+ background: 'var(--surface2)',
+ border: '1px solid var(--border)',
borderRadius: 8,
marginBottom: 16
}}>
- {
- const sum = Object.values(focusTemp).reduce((a, b) => a + b, 0)
- if (sum === 100) return 'white'
- return '#DC2626'
- })()
- }}>
- Summe:
+
+ Gewichtung gesamt:
- {
- const sum = Object.values(focusTemp).reduce((a, b) => a + b, 0)
- if (sum === 100) return 'white'
- return '#DC2626'
- })()
- }}>
- {Object.values(focusTemp).reduce((a, b) => a + b, 0)}%
+
+ {Object.values(focusTemp).reduce((a, b) => a + b, 0) / 10}
- {Object.values(focusTemp).reduce((a, b) => a + b, 0) !== 100 && (
-
- ⚠️ Summe muss 100% ergeben
-
- )}
+
+ 💡 Die Prozentanteile werden automatisch berechnet
+
{/* Action Buttons */}
@@ -394,12 +375,27 @@ export default function GoalsPage() {
className="btn-primary"
onClick={async () => {
const sum = Object.values(focusTemp).reduce((a, b) => a + b, 0)
- if (sum !== 100) {
- setError('Summe muss 100% ergeben')
+
+ if (sum === 0) {
+ setError('Mindestens ein Bereich muss gewichtet sein')
return
}
+
+ // Normalize to percentages
+ const normalized = {}
+ Object.keys(focusTemp).forEach(key => {
+ normalized[key] = Math.round(focusTemp[key] / sum * 100)
+ })
+
+ // Ensure sum is exactly 100 (adjust largest value if needed due to rounding)
+ const normalizedSum = Object.values(normalized).reduce((a, b) => a + b, 0)
+ if (normalizedSum !== 100) {
+ const largest = Object.entries(normalized).reduce((max, [k, v]) => v > max[1] ? [k, v] : max, ['', 0])
+ normalized[largest[0]] += (100 - normalizedSum)
+ }
+
try {
- await api.updateFocusAreas(focusTemp)
+ await api.updateFocusAreas(normalized)
showToast('✓ Fokus-Bereiche aktualisiert')
await loadData()
setFocusEditing(false)
@@ -408,7 +404,6 @@ export default function GoalsPage() {
setError(err.message || 'Fehler beim Speichern')
}
}}
- disabled={Object.values(focusTemp).reduce((a, b) => a + b, 0) !== 100}
style={{ flex: 1 }}
>
Speichern