From d13c2c7e2500daa56b2498846273d13c39745736 Mon Sep 17 00:00:00 2001 From: Lars Date: Sat, 21 Mar 2026 07:25:47 +0100 Subject: [PATCH] fix: add dashboard weight enforcement and fix hover tooltips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Dashboard QuickWeight: Feature limit enforcement hinzugefügt - Hover-Tooltip Fix: Button in div wrapper (disabled buttons zeigen keine nativen tooltips) - Error handling für Dashboard weight input - Konsistentes UX über alle Eingabe-Screens Co-Authored-By: Claude Opus 4.6 --- frontend/src/pages/CaliperScreen.jsx | 18 +++++--- frontend/src/pages/CircumScreen.jsx | 24 +++++----- frontend/src/pages/Dashboard.jsx | 67 +++++++++++++++++++++++----- frontend/src/pages/WeightScreen.jsx | 24 +++++----- 4 files changed, 94 insertions(+), 39 deletions(-) diff --git a/frontend/src/pages/CaliperScreen.jsx b/frontend/src/pages/CaliperScreen.jsx index 8940d8c..0b1564e 100644 --- a/frontend/src/pages/CaliperScreen.jsx +++ b/frontend/src/pages/CaliperScreen.jsx @@ -72,15 +72,19 @@ function CaliperForm({ form, setForm, profile, onSave, onCancel, saveLabel='Spei )}
- + +
{onCancel && } diff --git a/frontend/src/pages/CircumScreen.jsx b/frontend/src/pages/CircumScreen.jsx index 8d876b8..ea1fb5e 100644 --- a/frontend/src/pages/CircumScreen.jsx +++ b/frontend/src/pages/CircumScreen.jsx @@ -130,18 +130,22 @@ export default function CircumScreen() { {error} )} - + + {/* Liste */} diff --git a/frontend/src/pages/Dashboard.jsx b/frontend/src/pages/Dashboard.jsx index d9d6c59..5ec20b6 100644 --- a/frontend/src/pages/Dashboard.jsx +++ b/frontend/src/pages/Dashboard.jsx @@ -27,32 +27,75 @@ function QuickWeight({ onSaved }) { const [input, setInput] = useState('') const [saving, setSaving] = useState(false) const [saved, setSaved] = useState(false) + const [error, setError] = useState(null) + const [weightUsage, setWeightUsage] = useState(null) const today = dayjs().format('YYYY-MM-DD') + const loadUsage = () => { + api.getFeatureUsage().then(features => { + const weightFeature = features.find(f => f.feature_id === 'weight_entries') + setWeightUsage(weightFeature) + }).catch(err => console.error('Failed to load usage:', err)) + } + useEffect(()=>{ api.weightStats().then(s=>{ if(s?.latest?.date===today) setInput(String(s.latest.weight)) }) + loadUsage() },[]) const handleSave = async () => { const w=parseFloat(input); if(!w||w<20||w>300) return setSaving(true) - try{ await api.upsertWeight(today,w); setSaved(true); onSaved?.(); setTimeout(()=>setSaved(false),2000) } - finally{ setSaving(false) } + setError(null) + try{ + await api.upsertWeight(today,w) + setSaved(true) + await loadUsage() // Reload usage after save + onSaved?.() + setTimeout(()=>setSaved(false),2000) + } catch(err) { + console.error('Save failed:', err) + setError(err.message || 'Fehler beim Speichern') + setTimeout(()=>setError(null), 5000) + } finally { + setSaving(false) + } } + const isDisabled = saving || !input || (weightUsage && !weightUsage.allowed) + const tooltipText = weightUsage && !weightUsage.allowed + ? `Limit erreicht (${weightUsage.used}/${weightUsage.limit}). Kontaktiere den Admin oder warte bis zum nächsten Reset.` + : '' + return ( -
- setInput(e.target.value)} - onKeyDown={e=>e.key==='Enter'&&handleSave()}/> - kg - +
+ {error && ( +
+ {error} +
+ )} +
+ setInput(e.target.value)} + onKeyDown={e=>e.key==='Enter'&&!isDisabled&&handleSave()}/> + kg +
+ +
+
) } diff --git a/frontend/src/pages/WeightScreen.jsx b/frontend/src/pages/WeightScreen.jsx index d6d2e13..0f24a8a 100644 --- a/frontend/src/pages/WeightScreen.jsx +++ b/frontend/src/pages/WeightScreen.jsx @@ -111,18 +111,22 @@ export default function WeightScreen() { {error}
)} - + + {/* Chart */}