feat(fitness): redesign measure page with muscle-man map, inline edit, and desktop 2-col layout
- Weight + body fat cards share a unified .metric-card component with wheel + keyboard (Arrow/Shift+Arrow) stepping. Side-by-side on tablet and up. - Replaced body-parts accordion with a prominent card showing a cropped muscle-front silhouette and overlay dots/bands marking which regions have measurements. Shoulders + chest render as dotted tape-measure bands; other parts as dots. "Last measured" now relative (N days ago). - Desktop layout: .main-col (form + period tracker) left, history on right. Two columns center together at wider widths instead of drifting apart. Fitness layout detects measure index and bumps max-width to 1400px, matching nutrition. - Inline history edit: pencil swaps the row for a compact date/kg/% form (Enter saves, Escape cancels) via PUT /api/fitness/measurements. Full-edit link preserved for body-parts tweaks. - Body-parts history heading renamed to "Past measurements" / "Frühere Messungen" to avoid collision with the period tracker's own history. - "Profil bearbeiten" moved to the top-left of the main column. - Same-sides toggle in the body-parts flow now uses the shared Toggle component.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "homepage",
|
||||
"version": "1.45.1",
|
||||
"version": "1.46.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -311,6 +311,7 @@ const translations: Translations = {
|
||||
general: { en: 'General', de: 'Allgemein' },
|
||||
body_fat_pct: { en: 'Body Fat (%)', de: 'Körperfett (%)' },
|
||||
history: { en: 'History', de: 'Verlauf' },
|
||||
past_measurements: { en: 'Past measurements', de: 'Frühere Messungen' },
|
||||
|
||||
// SetTable
|
||||
set_header: { en: 'SET', de: 'SATZ' },
|
||||
|
||||
@@ -68,6 +68,9 @@
|
||||
!$page.url.pathname.startsWith(`/fitness/${s.nutrition}/food`) &&
|
||||
!$page.url.pathname.startsWith(`/fitness/${s.nutrition}/meals`)
|
||||
);
|
||||
const isMeasureIndex = $derived(
|
||||
/^\/fitness\/(measure|messen)\/?$/.test($page.url.pathname)
|
||||
);
|
||||
/** @param {number} secs */
|
||||
function formatElapsed(secs) {
|
||||
const m = Math.floor(secs / 60);
|
||||
@@ -100,7 +103,7 @@
|
||||
<UserHeader {user} />
|
||||
{/snippet}
|
||||
|
||||
<div class="fitness-content" style:--fitness-max-width={isNutritionPage ? '1400px' : null}>
|
||||
<div class="fitness-content" style:--fitness-max-width={isNutritionPage || isMeasureIndex ? '1400px' : null}>
|
||||
{@render children()}
|
||||
</div>
|
||||
</Header>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@
|
||||
import { toast } from '$lib/js/toast.svelte';
|
||||
import DatePicker from '$lib/components/DatePicker.svelte';
|
||||
import SaveFab from '$lib/components/SaveFab.svelte';
|
||||
import Toggle from '$lib/components/Toggle.svelte';
|
||||
import { bodyPartAccent } from '$lib/js/fitnessBodyParts';
|
||||
|
||||
let { data } = $props();
|
||||
@@ -427,10 +428,9 @@
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
<label class="same-toggle">
|
||||
<input type="checkbox" bind:checked={pv.same} />
|
||||
<span>{t('same_both_sides', lang)}</span>
|
||||
</label>
|
||||
<div class="same-toggle">
|
||||
<Toggle bind:checked={pv.same} label={t('same_both_sides', lang)} />
|
||||
</div>
|
||||
{:else}
|
||||
<div class="stepper" onwheel={(e) => onWheel(e, step.key, null)}>
|
||||
<button type="button" class="step-btn" onclick={() => bump(step.key, null, -0.5)} aria-label="-0.5">
|
||||
@@ -859,17 +859,6 @@
|
||||
|
||||
.same-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.45rem;
|
||||
font-size: 0.78rem;
|
||||
color: var(--color-text-secondary);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
.same-toggle input {
|
||||
accent-color: var(--color-primary);
|
||||
width: 0.95rem;
|
||||
height: 0.95rem;
|
||||
}
|
||||
|
||||
.panel { display: none; }
|
||||
|
||||
Reference in New Issue
Block a user