Compare commits

2 Commits

Author SHA1 Message Date
1e0dd27fa3 fix: shorten dashboard labels to "Burned" and "Covered"
All checks were successful
CI / update (push) Successful in 2m22s
Values already include units (kcal, km), so verbose labels were redundant.
Remove unused distance_covered i18n key.
2026-03-25 07:18:57 +01:00
9caa0fbc24 fix: preserve GPS data when recalculating workout sessions
Replace .save() with $set updateOne so only computed fields (totalVolume,
totalDistance, prs, gpsPreview) are written. Previously the full document
re-serialization could strip gpsTrack arrays.
2026-03-25 07:18:52 +01:00
3 changed files with 20 additions and 12 deletions

View File

@@ -72,8 +72,9 @@ const translations: Translations = {
workouts_plural: { en: 'Workouts', de: 'Trainings' }, workouts_plural: { en: 'Workouts', de: 'Trainings' },
lifted: { en: 'Lifted', de: 'Gehoben' }, lifted: { en: 'Lifted', de: 'Gehoben' },
est_kcal: { en: 'Est. kcal', de: 'Gesch. kcal' }, est_kcal: { en: 'Est. kcal', de: 'Gesch. kcal' },
burned: { en: 'Burned', de: 'Verbrannt' },
kcal_set_profile: { en: 'Set sex & height in', de: 'Geschlecht & Grösse unter' }, kcal_set_profile: { en: 'Set sex & height in', de: 'Geschlecht & Grösse unter' },
distance_covered: { en: 'Distance Covered', de: 'Zurückgelegt' }, covered: { en: 'Covered', de: 'Zurückgelegt' },
workouts_per_week: { en: 'Workouts per week', de: 'Trainings pro Woche' }, workouts_per_week: { en: 'Workouts per week', de: 'Trainings pro Woche' },
sex: { en: 'Sex', de: 'Geschlecht' }, sex: { en: 'Sex', de: 'Geschlecht' },
male: { en: 'Male', de: 'Männlich' }, male: { en: 'Male', de: 'Männlich' },

View File

@@ -40,7 +40,9 @@ export const POST: RequestHandler = async ({ params, locals }) => {
// Recompute totalVolume and totalDistance // Recompute totalVolume and totalDistance
let totalVolume = 0; let totalVolume = 0;
let totalDistance = 0; let totalDistance = 0;
for (const ex of workoutSession.exercises) { const gpsPreviewUpdates: Record<string, number[][]> = {};
for (let i = 0; i < workoutSession.exercises.length; i++) {
const ex = workoutSession.exercises[i];
const exercise = getExerciseById(ex.exerciseId); const exercise = getExerciseById(ex.exerciseId);
const metrics = getExerciseMetrics(exercise); const metrics = getExerciseMetrics(exercise);
const isCardio = metrics.includes('distance'); const isCardio = metrics.includes('distance');
@@ -56,7 +58,7 @@ export const POST: RequestHandler = async ({ params, locals }) => {
// Regenerate gpsPreview from gpsTrack if present // Regenerate gpsPreview from gpsTrack if present
if (ex.gpsTrack && ex.gpsTrack.length >= 2) { if (ex.gpsTrack && ex.gpsTrack.length >= 2) {
ex.gpsPreview = simplifyTrack(ex.gpsTrack); gpsPreviewUpdates[`exercises.${i}.gpsPreview`] = simplifyTrack(ex.gpsTrack);
} }
} }
@@ -120,15 +122,20 @@ export const POST: RequestHandler = async ({ params, locals }) => {
} }
} }
workoutSession.totalVolume = totalVolume > 0 ? totalVolume : undefined; // Use $set to only update computed fields, preserving gpsTrack data
workoutSession.totalDistance = totalDistance > 0 ? totalDistance : undefined; await WorkoutSession.updateOne({ _id: workoutSession._id }, {
workoutSession.prs = prs.length > 0 ? prs : undefined; $set: {
await workoutSession.save(); totalVolume: totalVolume > 0 ? totalVolume : undefined,
totalDistance: totalDistance > 0 ? totalDistance : undefined,
prs: prs.length > 0 ? prs : undefined,
...gpsPreviewUpdates
}
});
return json({ return json({
totalVolume: workoutSession.totalVolume, totalVolume: totalVolume > 0 ? totalVolume : undefined,
totalDistance: workoutSession.totalDistance, totalDistance: totalDistance > 0 ? totalDistance : undefined,
prs: workoutSession.prs?.length ?? 0 prs: prs.length
}); });
} catch (error) { } catch (error) {
console.error('Error recalculating session:', error); console.error('Error recalculating session:', error);

View File

@@ -145,7 +145,7 @@
<div class="lifetime-card kcal"> <div class="lifetime-card kcal">
<div class="card-icon"><Flame size={24} /></div> <div class="card-icon"><Flame size={24} /></div>
<div class="card-value">~{stats.kcalEstimate.kcal.toLocaleString()}<span class="card-unit">kcal</span></div> <div class="card-value">~{stats.kcalEstimate.kcal.toLocaleString()}<span class="card-unit">kcal</span></div>
<div class="card-label">{t('est_kcal', lang)}</div> <div class="card-label">{t('burned', lang)}</div>
{#if !hasDemographics} {#if !hasDemographics}
<div class="card-hint">{t('kcal_set_profile', lang)} <a href="/fitness/{fitnessSlugs(lang).measure}">{t('measure_title', lang)}</a></div> <div class="card-hint">{t('kcal_set_profile', lang)} <a href="/fitness/{fitnessSlugs(lang).measure}">{t('measure_title', lang)}</a></div>
{/if} {/if}
@@ -154,7 +154,7 @@
<div class="lifetime-card cardio"> <div class="lifetime-card cardio">
<div class="card-icon"><Route size={24} /></div> <div class="card-icon"><Route size={24} /></div>
<div class="card-value">{stats.totalCardioKm ?? 0}<span class="card-unit">km</span></div> <div class="card-value">{stats.totalCardioKm ?? 0}<span class="card-unit">km</span></div>
<div class="card-label">{t('distance_covered', lang)}</div> <div class="card-label">{t('covered', lang)}</div>
</div> </div>
</div> </div>