import { useState, useEffect, useRef } from 'react' import { useNavigate, useParams } from 'react-router-dom' import { Camera, CheckCircle, ChevronDown, ChevronUp, BookOpen } from 'lucide-react' import { api } from '../utils/api' import { calcBodyFat, METHOD_POINTS } from '../utils/calc' import { CIRCUMFERENCE_POINTS, CALIPER_POINTS, CALIPER_METHODS } from '../utils/guideData' import dayjs from 'dayjs' function Section({ title, open, onToggle, children, hint }) { return (
{title}
{hint && !open &&
{hint}
}
{open ? : }
{open &&
{children}
}
) } function NumInput({ label, sub, value, onChange, unit, min, max, step=0.1, guideText }) { return (
onChange(e.target.value==='' ? null : parseFloat(e.target.value))}/> {unit}
) } export default function NewMeasurement() { const { id } = useParams() const nav = useNavigate() const fileRef = useRef() const [profile, setProfile] = useState(null) const [saving, setSaving] = useState(false) const [saved, setSaved] = useState(false) const [photoPreview, setPhotoPreview] = useState(null) const [photoFile, setPhotoFile] = useState(null) const [openSections, setOpenSections] = useState({ basic:true, circum:true, caliper:false, notes:false }) const isEdit = !!id const [form, setForm] = useState({ date: dayjs().format('YYYY-MM-DD'), weight: null, c_neck:null, c_chest:null, c_waist:null, c_belly:null, c_hip:null, c_thigh:null, c_calf:null, c_arm:null, sf_method:'jackson3', sf_chest:null, sf_axilla:null, sf_triceps:null, sf_subscap:null, sf_suprailiac:null, sf_abdomen:null, sf_thigh:null, sf_calf_med:null, sf_lowerback:null, sf_biceps:null, notes:'' }) useEffect(() => { api.getProfile().then(setProfile) if (id) { api.getMeasurement(id).then(m => { setForm(f => ({...f, ...m})) }) } }, [id]) const toggle = s => setOpenSections(o => ({...o,[s]:!o[s]})) const set = (k,v) => setForm(f => ({...f,[k]:v})) const sex = profile?.sex || 'm' const age = profile?.dob ? Math.floor((Date.now()-new Date(profile.dob))/(365.25*24*3600*1000)) : 30 const height = profile?.height || 178 const weight = form.weight || 80 const sfPoints = METHOD_POINTS[form.sf_method]?.[sex] || [] const sfVals = {} sfPoints.forEach(k => { if (form[`sf_${k}`]) sfVals[k] = form[`sf_${k}`] }) const bfPct = Object.keys(sfVals).length===sfPoints.length ? Math.round(calcBodyFat(form.sf_method, sfVals, sex, age)*10)/10 : null const handlePhoto = e => { const file = e.target.files[0]; if(!file) return setPhotoFile(file); setPhotoPreview(URL.createObjectURL(file)) } const handleSave = async () => { setSaving(true) try { const payload = {...form} if (bfPct) { payload.body_fat_pct = bfPct payload.lean_mass = Math.round(weight*(1-bfPct/100)*10)/10 payload.fat_mass = Math.round(weight*(bfPct/100)*10)/10 } let mid = id if (id) { await api.updateMeasurement(id, payload) } else { const r = await api.createMeasurement(payload); mid = r.id } if (photoFile && mid) { const pr = await api.uploadPhoto(photoFile, mid) await api.updateMeasurement(mid, {photo_id: pr.id}) } setSaved(true); setTimeout(()=>nav('/'), 1200) } catch(e) { alert('Fehler beim Speichern: '+e.message) } finally { setSaving(false) } } return (

{isEdit ? 'Messung bearbeiten' : 'Neue Messung'}

{/* Grunddaten */}
toggle('basic')}>
set('date',e.target.value)}/>
set('weight',v)} unit="kg" min={30} max={250}/>
{/* Umfänge */}
toggle('circum')} hint="Hals, Brust, Taille, Bauch, Hüfte, Oberschenkel, Wade, Oberarm"> {CIRCUMFERENCE_POINTS.map(p => ( 50 ? p.where.substring(0,48)+'…' : p.where} value={form[p.id]} onChange={v=>set(p.id,v)} unit="cm" min={10} max={200}/> ))}
{/* Caliper */}
toggle('caliper')} hint="Optional – für präzise Körperfett-Messung">
Immer rechte Körperseite · Falte 1 cm abheben · 3× messen, Mittelwert nehmen nav('/guide')}>→ Anleitung
{sfPoints.map(k => { const p = CALIPER_POINTS[k] return p ? ( 50 ? p.where.substring(0,48)+'…' : p.where} value={form[`sf_${k}`]} onChange={v=>set(`sf_${k}`,v)} unit="mm" min={2} max={80}/> ) : null })} {bfPct !== null && (
{bfPct} %
Körperfett ({CALIPER_METHODS[form.sf_method]?.label})
{form.weight &&
Magermasse: {Math.round(form.weight*(1-bfPct/100)*10)/10} kg ·{' '} Fettmasse: {Math.round(form.weight*(bfPct/100)*10)/10} kg
}
)}
{/* Foto */}
Fortschrittsfoto
{photoPreview && preview}
{/* Notizen */}
toggle('notes')}>