2026-03-16 13:35:11 +01:00
import { useState } from 'react'
import { ChevronDown , ChevronUp } from 'lucide-react'
import { CIRCUMFERENCE _POINTS , CALIPER _POINTS , CALIPER _METHODS } from '../utils/guideData'
function PointCard ( { point , index } ) {
const [ open , setOpen ] = useState ( false )
return (
< div style = { { border : ` 1px solid ${ open ? point . color : 'var(--border)' } ` , borderRadius : 10 , marginBottom : 8 , overflow : 'hidden' , transition : 'border-color 0.15s' } } >
< div style = { { display : 'flex' , alignItems : 'center' , gap : 10 , padding : '11px 14px' , cursor : 'pointer' , background : open ? 'var(--surface2)' : 'var(--surface)' } }
onClick = { ( ) => setOpen ( o => ! o ) } >
< div style = { { width : 28 , height : 28 , borderRadius : '50%' , background : point . color , display : 'flex' , alignItems : 'center' , justifyContent : 'center' , flexShrink : 0 } } >
< span style = { { fontSize : 12 , fontWeight : 700 , color : 'white' } } > { index + 1 } < / span >
< / div >
< span style = { { flex : 1 , fontSize : 14 , fontWeight : 500 } } > { point . label } < / span >
{ open ? < ChevronUp size = { 16 } color = "var(--text3)" / > : < ChevronDown size = { 16 } color = "var(--text3)" / > }
< / div >
{ open && (
< div style = { { padding : '12px 14px' , borderTop : '1px solid var(--border)' , background : 'var(--surface)' } } >
{ [ [ '📍 Wo' , point . where ] , [ '🧍 Haltung' , point . posture ] , [ '📏 Band' , point . how ] , [ '💡 Tipp' , point . tip ] ] . map ( ( [ label , val ] ) => (
< div key = { label } style = { { display : 'grid' , gridTemplateColumns : '90px 1fr' , gap : '4px 8px' , marginBottom : 8 } } >
< span style = { { fontSize : 11 , fontWeight : 600 , color : 'var(--text3)' , textTransform : 'uppercase' , letterSpacing : '0.04em' , paddingTop : 2 } } > { label } < / span >
< span style = { { fontSize : 13 , color : 'var(--text2)' , lineHeight : 1.55 } } > { val } < / span >
< / div >
) ) }
< / div >
) }
< / div >
)
}
export default function GuidePage ( ) {
const [ tab , setTab ] = useState ( 'circum' )
const [ caliperMethod , setCaliperMethod ] = useState ( 'jackson3' )
const sex = 'm' // could read from profile
const methodPoints = CALIPER _METHODS [ caliperMethod ] ? . points _m || [ ]
return (
2026-04-05 10:14:07 +02:00
< div className = "capture-page" >
2026-03-16 13:35:11 +01:00
< h1 className = "page-title" > Messanleitung < / h1 >
< div className = "tabs" >
< button className = { 'tab' + ( tab === 'circum' ? ' active' : '' ) } onClick = { ( ) => setTab ( 'circum' ) } > Umfänge < / button >
< button className = { 'tab' + ( tab === 'caliper' ? ' active' : '' ) } onClick = { ( ) => setTab ( 'caliper' ) } > Caliper < / button >
< button className = { 'tab' + ( tab === 'tips' ? ' active' : '' ) } onClick = { ( ) => setTab ( 'tips' ) } > Allgemein < / button >
< / div >
{ tab === 'circum' && (
< div >
< div style = { { padding : '10px 14px' , background : 'var(--accent-light)' , borderRadius : 10 , marginBottom : 14 , fontSize : 13 , color : 'var(--accent-dark)' , lineHeight : 1.6 } } >
Klicke auf einen Messpunkt für genaue Anleitung zu Körperhaltung und Messung .
< / div >
{ CIRCUMFERENCE _POINTS . map ( ( p , i ) => < PointCard key = { p . id } point = { p } index = { i } / > ) }
< / div >
) }
{ tab === 'caliper' && (
< div >
< div style = { { marginBottom : 14 } } >
< div style = { { fontSize : 13 , fontWeight : 600 , color : 'var(--text3)' , marginBottom : 6 } } > METHODE WÄHLEN < / div >
< div style = { { display : 'flex' , flexDirection : 'column' , gap : 6 } } >
{ Object . entries ( CALIPER _METHODS ) . map ( ( [ key , m ] ) => (
< button key = { key } onClick = { ( ) => setCaliperMethod ( key ) }
style = { { padding : '9px 14px' , borderRadius : 10 , border : ` 1.5px solid ${ caliperMethod === key ? 'var(--accent)' : 'var(--border2)' } ` ,
background : caliperMethod === key ? 'var(--accent-light)' : 'var(--surface)' ,
color : caliperMethod === key ? 'var(--accent-dark)' : 'var(--text2)' ,
fontFamily : 'var(--font)' , fontSize : 13 , fontWeight : 500 , textAlign : 'left' , cursor : 'pointer' ,
display : 'flex' , justifyContent : 'space-between' , alignItems : 'center' } } >
< span > { m . label } < / span >
< span style = { { fontSize : 11 , opacity : 0.7 } } > { m . points _m . length } Punkte < / span >
< / button >
) ) }
< / div >
< / div >
< div style = { { padding : '10px 14px' , background : 'var(--warn-bg)' , borderRadius : 10 , marginBottom : 14 , fontSize : 13 , color : 'var(--warn-text)' , lineHeight : 1.6 } } >
< strong > Caliper - Grundregel : < / strong > Immer rechte Körperseite · Falte 1 cm neben dem Punkt abheben · Caliper 1 cm neben Fingern ansetzen · 2 Sek . warten · 3 × messen , Mittelwert nehmen
< / div >
{ methodPoints . map ( ( id , i ) => {
const p = CALIPER _POINTS [ id ]
if ( ! p ) return null
return < PointCard key = { id } point = { p } index = { i } / >
} ) }
< / div >
) }
{ tab === 'tips' && (
< div >
{ [
{ icon : '🌅' , title : 'Zeitpunkt' , text : 'Immer morgens nüchtern messen – vor dem Frühstück und vor dem Sport. Zu festen Zeiten messen für vergleichbare Werte.' } ,
{ icon : '👗' , title : 'Kleidung' , text : 'Immer in vergleichbarer Unterwäsche oder ohne Kleidung messen. Kleidung kann die Werte verfälschen.' } ,
{ icon : '📏' , title : 'Maßband' , text : 'Maßband flach und waagerecht anlegen – parallel zum Boden. Weder spannen noch locker lassen. 1 Finger Luft bei Hals-Messungen.' } ,
{ icon : '🔢' , title : 'Wiederholungen' , text : 'Jeden Wert 2× messen und den Durchschnitt notieren. Bei Abweichungen über 1 cm eine dritte Messung machen.' } ,
{ icon : '💧' , title : 'Wassereinlagerungen' , text : 'Nicht nach dem Sport, nach Alkohol, oder bei Krankheit messen. Beine schwellen gegen Abend an – Wade morgens messen.' } ,
{ icon : '📅' , title : 'Intervall' , text : 'Wöchentliche oder zweiwöchentliche Messungen reichen. Tägliche Schwankungen von 1– 2 kg sind normal und nicht aussagekräftig.' } ,
{ icon : '📸' , title : 'Fortschrittsfotos' , text : 'Fotos bei gleicher Beleuchtung und gleichem Hintergrund machen. Morgendlich nüchtern, gleiche Pose, gleiche Kamera-Distanz.' } ,
{ icon : '🔬' , title : 'Caliper vs. Maßband' , text : 'Caliper misst Unterhautfett direkt – genauer als Umfänge allein. Umfänge erfassen die Gesamtgröße inklusive Muskeln. Beide Werte kombiniert geben das vollständigste Bild.' } ,
] . map ( item => (
< div key = { item . title } className = "card section-gap" >
< div style = { { display : 'flex' , gap : 12 , alignItems : 'flex-start' } } >
< span style = { { fontSize : 22 , flexShrink : 0 } } > { item . icon } < / span >
< div >
< div style = { { fontWeight : 600 , fontSize : 14 , marginBottom : 4 } } > { item . title } < / div >
< div style = { { fontSize : 13 , color : 'var(--text2)' , lineHeight : 1.6 } } > { item . text } < / div >
< / div >
< / div >
< / div >
) ) }
< / div >
) }
< / div >
)
}