Sign in to view your workouts
Your workout history, personal records, and logged sessions are private to your account. Sign in with Google to continue.
import { useAuth, useCollection, playSound, renderChart } from '@deplixo/sdk'; // DEPLOY_CONFIG: {"cron": [{"name": "weekly_training_stats_summary", "schedule": "0 9 * * 1", "action": "event", "config": {"event_type": "weekly_training_stats_summary"}}]} import { useEffect, useMemo, useRef, useState } from 'react'; import { WorkoutLogger } from './components/WorkoutLogger.jsx'; import { ExerciseHistory } from './components/ExerciseHistory.jsx'; import { RestTimer } from './components/RestTimer.jsx'; function ChartsView({ user }) { const workoutsCollection = useCollection('workouts', { personal: true }); const workouts = workoutsCollection.items || []; const loading = workoutsCollection.loading; const [selectedExercise, setSelectedExercise] = useState(''); const progressionCanvasRef = useRef(null); const weeklyVolumeCanvasRef = useRef(null); const parsedWorkouts = useMemo(() => { return workouts .map((item) => { const data = item?.data || item || {}; const exercises = Array.isArray(data.exercises) ? data.exercises : []; return { ...data, id: item?.id || data.id, createdAt: data.createdAt || item?.createdAt || data.date || item?.date, exercises, }; }) .filter((w) => w.exercises.length > 0) .sort((a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0)); }, [workouts]); const exerciseNames = useMemo(() => { const names = new Set(); parsedWorkouts.forEach((workout) => { workout.exercises.forEach((exercise) => { if (exercise?.name) names.add(exercise.name); }); }); return Array.from(names).sort((a, b) => a.localeCompare(b)); }, [parsedWorkouts]); useEffect(() => { if (!selectedExercise && exerciseNames.length > 0) { setSelectedExercise(exerciseNames[0]); } }, [exerciseNames, selectedExercise]); const progressionData = useMemo(() => { if (!selectedExercise) return { labels: [], data: [] }; const points = []; parsedWorkouts.forEach((workout) => { workout.exercises.forEach((exercise) => { if (exercise?.name !== selectedExercise) return; const sets = Array.isArray(exercise.sets) ? exercise.sets : []; const maxWeight = sets.reduce((max, set) => { const weight = Number(set?.weight || 0); return Number.isFinite(weight) && weight > max ? weight : max; }, 0); points.push({ label: new Date(workout.createdAt).toLocaleDateString(), value: maxWeight, }); }); }); return { labels: points.map((p) => p.label), data: points.map((p) => p.value), }; }, [parsedWorkouts, selectedExercise]); const weeklyVolumeData = useMemo(() => { const weekMap = new Map(); parsedWorkouts.forEach((workout) => { const date = new Date(workout.createdAt); if (Number.isNaN(date.getTime())) return; const start = new Date(date); start.setDate(date.getDate() - date.getDay()); start.setHours(0, 0, 0, 0); const weekKey = start.toISOString(); let volume = 0; workout.exercises.forEach((exercise) => { const sets = Array.isArray(exercise.sets) ? exercise.sets : []; sets.forEach((set) => { const reps = Number(set?.reps || 0); const weight = Number(set?.weight || 0); if (Number.isFinite(reps) && Number.isFinite(weight)) { volume += reps * weight; } }); }); weekMap.set(weekKey, (weekMap.get(weekKey) || 0) + volume); }); const ordered = Array.from(weekMap.entries()) .sort((a, b) => new Date(a[0]) - new Date(b[0])) .slice(-8); return { labels: ordered.map(([week]) => new Date(week).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })), data: ordered.map(([, volume]) => volume), }; }, [parsedWorkouts]); useEffect(() => { if (progressionCanvasRef.current && progressionData.data.length > 0) { renderChart(progressionCanvasRef.current, { type: 'line', data: { labels: progressionData.labels, datasets: [ { label: `${selectedExercise} weight progression`, data: progressionData.data, }, ], }, }); } }, [progressionData, selectedExercise]); useEffect(() => { if (weeklyVolumeCanvasRef.current && weeklyVolumeData.data.length > 0) { renderChart(weeklyVolumeCanvasRef.current, { type: 'bar', data: { labels: weeklyVolumeData.labels, datasets: [ { label: 'Weekly Volume', data: weeklyVolumeData.data, }, ], }, }); } }, [weeklyVolumeData]); if (loading) { return
Log workouts first, then come back to view weight progression and weekly volume charts.
Workout Tracker
Your workout history, personal records, and logged sessions are private to your account. Sign in with Google to continue.
Workout Tracker