feat: Update capture page layout for improved responsiveness and organization across multiple screens
All checks were successful
Deploy Development / deploy (push) Successful in 46s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s

This commit is contained in:
Lars 2026-04-05 10:14:07 +02:00
parent 630a3de88a
commit a639d08037
14 changed files with 45 additions and 18 deletions

View File

@ -3,7 +3,7 @@
> **Gitea:** [#30 Responsive UI](http://192.168.2.144:3000/Lars/mitai-jinkendo/issues/30)
> **Spec:** `.claude/docs/functional/RESPONSIVE_UI.md`
> **Breakpoint:** `<1024px` = Mobile (Bottom-Nav, bestehendes Verhalten), `≥1024px` = Desktop (Sidebar 220px)
> **Letzte Plan-Aktualisierung:** 2026-04-04 (P5)
> **Letzte Plan-Aktualisierung:** 2026-04-04 (P6; P7 Admin bewusst offen)
---
@ -17,8 +17,8 @@
| P3 | Dashboard (Desktop-Grid) | ☑ erledigt | 4-spaltige Kennzahlen; Begrüßung; Ernährung/Aktivität 2-spaltig |
| P4 | Verlauf (Tabs links / Content rechts) | ☑ erledigt | `History.jsx` + `.history-*` in `app.css`; Tab-State bei `location.state.tab` |
| P5 | Analyse (Prompts links / Ergebnis rechts) | ☑ erledigt | `Analysis.jsx` + `.analysis-split*` in `app.css` |
| P6 | Erfassung / Capture & Formularseiten | ☐ pending | |
| P7 | Admin & restliche Vollbreiten-Seiten | ☐ pending | |
| P6 | Erfassung / Capture & Formularseiten | ☑ erledigt | `.capture-page` / `.capture-page--wide` in `app.css`; CaptureHub, Wizard, GewichtZiele, Guide, Ernährung/Aktivität/Vital/Schlaf breiter |
| P7 | Admin & restliche Vollbreiten-Seiten | ⏸ Konzeption | Layout nach Abstimmung; nicht mit P6 mitgezogen |
| P8 | Abschluss, Regression, Spec-Pflege | ☐ pending | |
**Status-Legende:** `☐ pending` · `◐ in Arbeit` · `☑ erledigt` · `⏸ blockiert`

View File

@ -344,6 +344,25 @@ body { font-family: var(--font); background: var(--bg); color: var(--text1); -we
}
}
/* P6 / RESPONSIVE_UI §5.4 Erfassung: Desktop zentriert; data-lastige Seiten etwas breiter */
.capture-page {
width: 100%;
max-width: 100%;
box-sizing: border-box;
}
@media (min-width: 1024px) {
.capture-page {
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.capture-page--wide {
max-width: 900px;
}
}
.muted { color: var(--text3); font-size: 13px; }
.empty-state { text-align: center; padding: 48px 16px; color: var(--text3); }
.empty-state h3 { font-size: 16px; color: var(--text2); margin-bottom: 6px; }

View File

@ -254,7 +254,7 @@ export default function ActivityPage() {
}
return (
<div>
<div className="capture-page capture-page--wide">
<h1 className="page-title">Aktivität</h1>
<div className="tabs" style={{overflowX:'auto',flexWrap:'nowrap'}}>

View File

@ -160,7 +160,7 @@ export default function CaliperScreen() {
}
return (
<div>
<div className="capture-page">
<div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:16}}>
<h1 className="page-title" style={{margin:0}}>Caliper</h1>
<button className="btn btn-secondary" style={{fontSize:12,padding:'6px 10px'}} onClick={()=>nav('/guide')}>

View File

@ -85,7 +85,7 @@ const ENTRIES = [
export default function CaptureHub() {
const nav = useNavigate()
return (
<div>
<div className="capture-page">
<h1 className="page-title">Erfassen</h1>
<div style={{display:'flex',flexDirection:'column',gap:10}}>
{ENTRIES.map(e => (

View File

@ -85,7 +85,7 @@ export default function CircumScreen() {
}
return (
<div>
<div className="capture-page">
<div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:16}}>
<h1 className="page-title" style={{margin:0}}>Umfänge</h1>
<button className="btn btn-secondary" style={{fontSize:12,padding:'6px 10px'}} onClick={()=>nav('/guide')}>

View File

@ -117,7 +117,7 @@ export default function CustomGoalsPage() {
}
return (
<div style={{ paddingBottom: 80 }}>
<div className="capture-page" style={{ paddingBottom: 80 }}>
{/* Header */}
<div style={{
background: 'linear-gradient(135deg, var(--accent) 0%, var(--accent-dark) 100%)',

View File

@ -36,7 +36,7 @@ export default function GuidePage() {
const methodPoints = CALIPER_METHODS[caliperMethod]?.points_m || []
return (
<div>
<div className="capture-page">
<h1 className="page-title">Messanleitung</h1>
<div className="tabs">

View File

@ -344,7 +344,7 @@ export default function MeasureWizard() {
if (done) {
return (
<div style={{display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',
<div className="capture-page" style={{display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',
minHeight:'60vh',gap:16,textAlign:'center'}}>
<div style={{fontSize:48}}></div>
<h2 style={{fontSize:20,fontWeight:700}}>Gespeichert!</h2>
@ -361,11 +361,19 @@ export default function MeasureWizard() {
)
}
if (mode === 'circum') return <CircumWizard onDone={()=>setDone(true)} onCancel={()=>setMode(null)}/>
if (mode === 'caliper') return <CaliperWizard onDone={()=>setDone(true)} onCancel={()=>setMode(null)} profile={profile}/>
if (mode === 'circum') return (
<div className="capture-page">
<CircumWizard onDone={()=>setDone(true)} onCancel={()=>setMode(null)}/>
</div>
)
if (mode === 'caliper') return (
<div className="capture-page">
<CaliperWizard onDone={()=>setDone(true)} onCancel={()=>setMode(null)} profile={profile}/>
</div>
)
return (
<div>
<div className="capture-page">
<h1 className="page-title">Assistent</h1>
<p style={{fontSize:13,color:'var(--text2)',marginBottom:20,lineHeight:1.6}}>
Der Assistent führt dich Schritt für Schritt durch die Messung mit Anleitung für jeden Messpunkt.

View File

@ -802,7 +802,7 @@ export default function NutritionPage() {
useEffect(() => { load() }, [])
return (
<div>
<div className="capture-page capture-page--wide">
<h1 className="page-title">Ernährung</h1>
{/* Input Method Tabs */}

View File

@ -177,7 +177,7 @@ export default function RestDaysPage() {
}
return (
<div>
<div className="capture-page">
<h1 className="page-title">Ruhetage</h1>
{/* Toast Notification */}

View File

@ -142,7 +142,7 @@ export default function SleepPage() {
}
return (
<div style={{ padding: '16px 16px 80px' }}>
<div className="capture-page capture-page--wide" style={{ padding: '16px 16px 80px' }}>
{/* Toast Notification */}
{toast && (
<div style={{

View File

@ -1064,7 +1064,7 @@ export default function VitalsPage() {
}
return (
<div>
<div className="capture-page capture-page--wide">
<h1 className="page-title">Vitalwerte</h1>
<div className="tabs" style={{ overflowX: 'auto', flexWrap: 'nowrap' }}>

View File

@ -78,7 +78,7 @@ export default function WeightScreen() {
const avgAll = weights.length ? Math.round(weights.reduce((a,b)=>a+b,0)/weights.length*10)/10 : null
return (
<div>
<div className="capture-page">
<h1 className="page-title">Gewicht</h1>
{/* Eingabe */}