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