|
<!DOCTYPE html> |
|
<html lang="fr"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Track Lift - Suivi de Musculation</title> |
|
<style> |
|
:root { |
|
--bg-dark: #121212; |
|
--bg-card: #1e1e1e; |
|
--text-light: #e0e0e0; |
|
--accent: #4CAF50; |
|
--accent-dark: #3a8a3d; |
|
--danger: #f44336; |
|
} |
|
|
|
* { |
|
margin: 0; |
|
padding: 0; |
|
box-sizing: border-box; |
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
|
} |
|
|
|
body { |
|
background-color: var(--bg-dark); |
|
color: var(--text-light); |
|
min-height: 100vh; |
|
padding-bottom: 80px; |
|
} |
|
|
|
.container { |
|
width: 100%; |
|
max-width: 800px; |
|
margin: 0 auto; |
|
padding: 1rem; |
|
} |
|
|
|
header { |
|
padding: 1rem 0; |
|
text-align: center; |
|
border-bottom: 1px solid #333; |
|
margin-bottom: 1rem; |
|
} |
|
|
|
h1, h2, h3 { |
|
color: var(--accent); |
|
} |
|
|
|
.btn { |
|
background-color: var(--accent); |
|
color: white; |
|
border: none; |
|
padding: 0.6rem 1.2rem; |
|
border-radius: 4px; |
|
cursor: pointer; |
|
font-weight: bold; |
|
transition: background-color 0.2s; |
|
} |
|
|
|
.btn:hover { |
|
background-color: var(--accent-dark); |
|
} |
|
|
|
.btn-outline { |
|
background-color: transparent; |
|
color: var(--accent); |
|
border: 1px solid var(--accent); |
|
} |
|
|
|
.btn-danger { |
|
background-color: var(--danger); |
|
} |
|
|
|
input, select, textarea { |
|
width: 100%; |
|
padding: 0.6rem; |
|
margin-bottom: 1rem; |
|
background-color: #2a2a2a; |
|
border: 1px solid #444; |
|
border-radius: 4px; |
|
color: var(--text-light); |
|
} |
|
|
|
input[type="checkbox"] { |
|
width: auto; |
|
margin-right: 0.5rem; |
|
} |
|
|
|
.card { |
|
background-color: var(--bg-card); |
|
border-radius: 8px; |
|
padding: 1rem; |
|
margin-bottom: 1rem; |
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); |
|
} |
|
|
|
.form-group { |
|
margin-bottom: 1rem; |
|
} |
|
|
|
.form-row { |
|
display: flex; |
|
gap: 0.5rem; |
|
margin-bottom: 0.5rem; |
|
} |
|
|
|
.form-row > * { |
|
flex: 1; |
|
margin-bottom: 0; |
|
} |
|
|
|
label { |
|
display: block; |
|
margin-bottom: 0.3rem; |
|
color: #bbb; |
|
} |
|
|
|
.exercise { |
|
border-left: 3px solid var(--accent); |
|
padding-left: 1rem; |
|
margin-bottom: 1.5rem; |
|
} |
|
|
|
.exercise-header { |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
margin-bottom: 0.5rem; |
|
} |
|
|
|
.series-container { |
|
margin-left: 0.5rem; |
|
margin-top: 0.5rem; |
|
} |
|
|
|
.series { |
|
background-color: #252525; |
|
padding: 0.7rem; |
|
border-radius: 4px; |
|
margin-bottom: 0.5rem; |
|
} |
|
|
|
.nav-bottom { |
|
position: fixed; |
|
bottom: 0; |
|
left: 0; |
|
width: 100%; |
|
background-color: #1a1a1a; |
|
display: flex; |
|
justify-content: space-around; |
|
padding: 0.7rem 0; |
|
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.3); |
|
} |
|
|
|
.nav-item { |
|
text-align: center; |
|
color: #888; |
|
text-decoration: none; |
|
font-size: 0.85rem; |
|
transition: color 0.2s; |
|
} |
|
|
|
.nav-item.active { |
|
color: var(--accent); |
|
} |
|
|
|
.nav-icon { |
|
font-size: 1.4rem; |
|
margin-bottom: 0.2rem; |
|
} |
|
|
|
.workout-card { |
|
border-left: 3px solid var(--accent); |
|
cursor: pointer; |
|
transition: transform 0.2s; |
|
} |
|
|
|
.workout-card:hover { |
|
transform: translateX(5px); |
|
} |
|
|
|
.workout-header { |
|
display: flex; |
|
justify-content: space-between; |
|
} |
|
|
|
.stat-card { |
|
text-align: center; |
|
padding: 1rem; |
|
} |
|
|
|
.stat-value { |
|
font-size: 1.8rem; |
|
color: var(--accent); |
|
font-weight: bold; |
|
} |
|
|
|
.stats-grid { |
|
display: grid; |
|
grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); |
|
gap: 1rem; |
|
} |
|
|
|
.hidden { |
|
display: none; |
|
} |
|
|
|
#app-container > div { |
|
display: none; |
|
} |
|
|
|
#app-container > div.active { |
|
display: block; |
|
} |
|
|
|
.flex-between { |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
} |
|
|
|
.badge { |
|
background-color: var(--accent); |
|
color: white; |
|
padding: 0.2rem 0.5rem; |
|
border-radius: 10px; |
|
font-size: 0.8rem; |
|
} |
|
|
|
.spinner { |
|
border: 4px solid rgba(0, 0, 0, 0.1); |
|
width: 36px; |
|
height: 36px; |
|
border-radius: 50%; |
|
border-left-color: var(--accent); |
|
animation: spin 1s linear infinite; |
|
margin: 2rem auto; |
|
display: none; |
|
} |
|
|
|
@keyframes spin { |
|
0% { transform: rotate(0deg); } |
|
100% { transform: rotate(360deg); } |
|
} |
|
|
|
.exercise-summary { |
|
margin: 0.3rem 0; |
|
padding: 0.3rem 0; |
|
border-bottom: 1px solid #333; |
|
} |
|
|
|
.satisfaction { |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
flex-direction: column; |
|
margin-top: 1rem; |
|
} |
|
|
|
.satisfaction-value { |
|
font-size: 2rem; |
|
color: var(--accent); |
|
margin-top: 0.5rem; |
|
} |
|
|
|
|
|
@media (max-width: 600px) { |
|
.form-row { |
|
flex-direction: column; |
|
gap: 0; |
|
} |
|
|
|
.container { |
|
padding: 0.5rem; |
|
} |
|
|
|
h1 { |
|
font-size: 1.5rem; |
|
} |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="container"> |
|
<header> |
|
<h1>Track Lift</h1> |
|
<p>Suivi de vos séances de musculation</p> |
|
</header> |
|
|
|
<div id="app-container"> |
|
|
|
<div id="home-page" class="active"> |
|
<div class="flex-between"> |
|
<h2>Mes séances</h2> |
|
<button id="new-workout-btn" class="btn">Nouvelle séance</button> |
|
</div> |
|
|
|
<div id="workouts-list" class="workout-list"> |
|
|
|
<div class="spinner"></div> |
|
<p id="empty-workout-message" class="hidden" style="text-align: center; margin-top: 2rem;"> |
|
Aucune séance enregistrée. Créez votre première séance avec le bouton ci-dessus. |
|
</p> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="new-workout-page" class="hidden"> |
|
<div class="flex-between"> |
|
<h2>Nouvelle séance</h2> |
|
<button id="save-workout-btn" class="btn">Enregistrer</button> |
|
</div> |
|
|
|
<div class="card"> |
|
<div class="form-group"> |
|
<label for="workout-name">Nom de la séance</label> |
|
<input type="text" id="workout-name" placeholder="Ex: Push, Jambes, Full body..."> |
|
</div> |
|
|
|
<div class="form-row"> |
|
<div class="form-group"> |
|
<label for="workout-date">Date</label> |
|
<input type="date" id="workout-date"> |
|
</div> |
|
<div class="form-group"> |
|
<label for="workout-duration">Durée (minutes)</label> |
|
<input type="number" id="workout-duration" min="1" placeholder="60"> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<h3 style="margin: 1rem 0;">Exercices</h3> |
|
<div id="exercises-container"> |
|
|
|
</div> |
|
|
|
<button id="add-exercise-btn" class="btn btn-outline" style="width: 100%; margin-top: 1rem;"> |
|
+ Ajouter un exercice |
|
</button> |
|
|
|
<div class="card" style="margin-top: 2rem;"> |
|
<div class="form-group"> |
|
<label for="satisfaction">Niveau de satisfaction (1-100%)</label> |
|
<input type="range" id="satisfaction" min="1" max="100" value="75"> |
|
<div class="satisfaction"> |
|
<span>Satisfaction</span> |
|
<div class="satisfaction-value">75%</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="workout-details-page" class="hidden"> |
|
<div class="flex-between"> |
|
<h2 id="detail-workout-name">Détail de la séance</h2> |
|
<button id="back-to-home" class="btn btn-outline">Retour</button> |
|
</div> |
|
|
|
<div class="card"> |
|
<div class="workout-details-info"> |
|
<div class="form-row"> |
|
<p><strong>Date:</strong> <span id="detail-date"></span></p> |
|
<p><strong>Durée:</strong> <span id="detail-duration"></span> min</p> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="stats-grid" style="margin-top: 1rem;"> |
|
<div class="card stat-card"> |
|
<div class="stat-value" id="detail-tonnage">0</div> |
|
<div>Tonnage total (kg)</div> |
|
</div> |
|
<div class="card stat-card"> |
|
<div class="stat-value" id="detail-satisfaction">0%</div> |
|
<div>Satisfaction</div> |
|
</div> |
|
<div class="card stat-card"> |
|
<div class="stat-value" id="detail-exercises-count">0</div> |
|
<div>Exercices</div> |
|
</div> |
|
</div> |
|
|
|
<h3 style="margin: 1.5rem 0 1rem;">Exercices réalisés</h3> |
|
<div id="detail-exercises-container"> |
|
|
|
</div> |
|
|
|
<button id="delete-workout-btn" class="btn btn-danger" style="width: 100%; margin-top: 2rem;"> |
|
Supprimer cette séance |
|
</button> |
|
</div> |
|
|
|
|
|
<div id="stats-page" class="hidden"> |
|
<h2>Statistiques</h2> |
|
|
|
<div class="stats-grid"> |
|
<div class="card stat-card"> |
|
<div class="stat-value" id="stats-workout-count">0</div> |
|
<div>Séances totales</div> |
|
</div> |
|
<div class="card stat-card"> |
|
<div class="stat-value" id="stats-avg-tonnage">0</div> |
|
<div>Tonnage moyen</div> |
|
</div> |
|
<div class="card stat-card"> |
|
<div class="stat-value" id="stats-avg-satisfaction">0%</div> |
|
<div>Satisfaction moyenne</div> |
|
</div> |
|
</div> |
|
|
|
<h3 style="margin: 1.5rem 0 1rem;">Dernières tendances</h3> |
|
<div class="card"> |
|
<p style="text-align: center; margin: 1rem 0;"> |
|
Les statistiques détaillées seront calculées après plusieurs séances enregistrées. |
|
</p> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<nav class="nav-bottom"> |
|
<a href="#" class="nav-item active" data-page="home-page"> |
|
<div class="nav-icon">📋</div> |
|
<div>Séances</div> |
|
</a> |
|
<a href="#" class="nav-item" data-page="stats-page"> |
|
<div class="nav-icon">📊</div> |
|
<div>Stats</div> |
|
</a> |
|
</nav> |
|
|
|
<script> |
|
|
|
let workouts = []; |
|
const STORAGE_KEY = 'workout-tracker-data'; |
|
|
|
|
|
const appContainer = document.getElementById('app-container'); |
|
const navItems = document.querySelectorAll('.nav-item'); |
|
const newWorkoutBtn = document.getElementById('new-workout-btn'); |
|
const saveWorkoutBtn = document.getElementById('save-workout-btn'); |
|
const addExerciseBtn = document.getElementById('add-exercise-btn'); |
|
const exercisesContainer = document.getElementById('exercises-container'); |
|
const workoutsList = document.getElementById('workouts-list'); |
|
const backToHomeBtn = document.getElementById('back-to-home'); |
|
const deleteWorkoutBtn = document.getElementById('delete-workout-btn'); |
|
const satisfactionRange = document.getElementById('satisfaction'); |
|
const satisfactionValue = document.querySelector('.satisfaction-value'); |
|
const emptyWorkoutMessage = document.getElementById('empty-workout-message'); |
|
|
|
|
|
let currentWorkoutId = null; |
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
loadWorkouts(); |
|
renderWorkoutsList(); |
|
initEventListeners(); |
|
setTodayDate(); |
|
}); |
|
|
|
|
|
function setTodayDate() { |
|
const today = new Date().toISOString().split('T')[0]; |
|
document.getElementById('workout-date').value = today; |
|
} |
|
|
|
|
|
function loadWorkouts() { |
|
const savedData = localStorage.getItem(STORAGE_KEY); |
|
if (savedData) { |
|
workouts = JSON.parse(savedData); |
|
} |
|
} |
|
|
|
|
|
function saveWorkouts() { |
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(workouts)); |
|
} |
|
|
|
|
|
function initEventListeners() { |
|
|
|
navItems.forEach(item => { |
|
item.addEventListener('click', (e) => { |
|
e.preventDefault(); |
|
const targetPage = item.getAttribute('data-page'); |
|
|
|
|
|
document.querySelectorAll('#app-container > div').forEach(page => { |
|
page.classList.remove('active'); |
|
}); |
|
document.getElementById(targetPage).classList.add('active'); |
|
|
|
|
|
navItems.forEach(navItem => navItem.classList.remove('active')); |
|
item.classList.add('active'); |
|
|
|
|
|
if (targetPage === 'stats-page') { |
|
updateStats(); |
|
} |
|
}); |
|
}); |
|
|
|
|
|
newWorkoutBtn.addEventListener('click', () => { |
|
showPage('new-workout-page'); |
|
clearNewWorkoutForm(); |
|
currentWorkoutId = null; |
|
}); |
|
|
|
|
|
saveWorkoutBtn.addEventListener('click', saveWorkout); |
|
|
|
|
|
addExerciseBtn.addEventListener('click', addExercise); |
|
|
|
|
|
backToHomeBtn.addEventListener('click', () => { |
|
showPage('home-page'); |
|
}); |
|
|
|
|
|
deleteWorkoutBtn.addEventListener('click', deleteWorkout); |
|
|
|
|
|
satisfactionRange.addEventListener('input', () => { |
|
satisfactionValue.textContent = `${satisfactionRange.value}%`; |
|
}); |
|
} |
|
|
|
|
|
function showPage(pageId) { |
|
document.querySelectorAll('#app-container > div').forEach(page => { |
|
page.classList.remove('active'); |
|
}); |
|
document.getElementById(pageId).classList.add('active'); |
|
|
|
|
|
const navItem = document.querySelector(`.nav-item[data-page="${pageId}"]`); |
|
if (navItem) { |
|
navItems.forEach(item => item.classList.remove('active')); |
|
navItem.classList.add('active'); |
|
} |
|
} |
|
|
|
|
|
function addExercise() { |
|
const exerciseId = `exercise-${Date.now()}`; |
|
const exerciseDiv = document.createElement('div'); |
|
exerciseDiv.className = 'exercise card'; |
|
exerciseDiv.setAttribute('data-exercise-id', exerciseId); |
|
|
|
exerciseDiv.innerHTML = ` |
|
<div class="exercise-header"> |
|
<input type="text" placeholder="Nom de l'exercice" class="exercise-name"> |
|
<button class="btn btn-danger remove-exercise" style="padding: 0.3rem 0.6rem;">×</button> |
|
</div> |
|
<div class="form-row"> |
|
<div class="form-group"> |
|
<label> |
|
<input type="checkbox" class="unilateral-checkbox"> Exercice unilatéral |
|
</label> |
|
</div> |
|
</div> |
|
<div class="series-container"> |
|
<!-- Les séries seront ajoutées ici --> |
|
</div> |
|
<button class="btn btn-outline add-series" style="width: 100%; margin-top: 0.5rem;"> |
|
+ Ajouter une série |
|
</button> |
|
`; |
|
|
|
exercisesContainer.appendChild(exerciseDiv); |
|
|
|
|
|
const removeBtn = exerciseDiv.querySelector('.remove-exercise'); |
|
removeBtn.addEventListener('click', () => { |
|
exerciseDiv.remove(); |
|
}); |
|
|
|
const addSeriesBtn = exerciseDiv.querySelector('.add-series'); |
|
addSeriesBtn.addEventListener('click', () => { |
|
addSeries(exerciseDiv.querySelector('.series-container')); |
|
}); |
|
|
|
|
|
addSeries(exerciseDiv.querySelector('.series-container')); |
|
} |
|
|
|
|
|
function addSeries(container) { |
|
const seriesId = `series-${Date.now()}`; |
|
const seriesDiv = document.createElement('div'); |
|
seriesDiv.className = 'series'; |
|
seriesDiv.setAttribute('data-series-id', seriesId); |
|
|
|
seriesDiv.innerHTML = ` |
|
<div class="form-row"> |
|
<div class="form-group"> |
|
<label>Répétitions</label> |
|
<input type="number" class="reps" min="1" placeholder="12"> |
|
</div> |
|
<div class="form-group"> |
|
<label>Charge (kg)</label> |
|
<input type="number" class="weight" min="0" step="0.5" placeholder="20"> |
|
</div> |
|
<div class="form-group" style="flex: 0.5;"> |
|
<label> |
|
<input type="checkbox" class="degressive-checkbox"> Série dégressive |
|
</label> |
|
</div> |
|
<button class="btn btn-danger remove-series" style="align-self: flex-end; padding: 0.3rem 0.6rem; flex: 0.2;">×</button> |
|
</div> |
|
`; |
|
|
|
container.appendChild(seriesDiv); |
|
|
|
|
|
const removeBtn = seriesDiv.querySelector('.remove-series'); |
|
removeBtn.addEventListener('click', () => { |
|
seriesDiv.remove(); |
|
}); |
|
} |
|
|
|
|
|
function saveWorkout() { |
|
|
|
const workoutName = document.getElementById('workout-name').value.trim(); |
|
const workoutDate = document.getElementById('workout-date').value; |
|
const workoutDuration = parseInt(document.getElementById('workout-duration').value) || 0; |
|
const satisfaction = parseInt(document.getElementById('satisfaction').value); |
|
|
|
|
|
if (!workoutName) { |
|
alert("Veuillez saisir un nom pour la séance"); |
|
return; |
|
} |
|
|
|
if (!workoutDate) { |
|
alert("Veuillez saisir une date"); |
|
return; |
|
} |
|
|
|
if (workoutDuration <= 0) { |
|
alert("Veuillez saisir une durée valide"); |
|
return; |
|
} |
|
|
|
|
|
const exercises = []; |
|
const exerciseElements = exercisesContainer.querySelectorAll('.exercise'); |
|
|
|
if (exerciseElements.length === 0) { |
|
alert("Ajoutez au moins un exercice"); |
|
return; |
|
} |
|
|
|
for (const exerciseEl of exerciseElements) { |
|
const exerciseName = exerciseEl.querySelector('.exercise-name').value.trim(); |
|
const isUnilateral = exerciseEl.querySelector('.unilateral-checkbox').checked; |
|
|
|
if (!exerciseName) { |
|
alert("Veuillez saisir un nom pour chaque exercice"); |
|
return; |
|
} |
|
|
|
|
|
const series = []; |
|
const seriesElements = exerciseEl.querySelectorAll('.series'); |
|
|
|
if (seriesElements.length === 0) { |
|
alert(`Ajoutez au moins une série à l'exercice "${exerciseName}"`); |
|
return; |
|
} |
|
|
|
for (const seriesEl of seriesElements) { |
|
const reps = parseInt(seriesEl.querySelector('.reps').value) || 0; |
|
const weight = parseFloat(seriesEl.querySelector('.weight').value) || 0; |
|
const isDegressive = seriesEl.querySelector('.degressive-checkbox').checked; |
|
|
|
if (reps <= 0) { |
|
alert(`Veuillez saisir un nombre de répétitions valide pour l'exercice "${exerciseName}"`); |
|
return; |
|
} |
|
|
|
series.push({ |
|
reps, |
|
weight, |
|
isDegressive |
|
}); |
|
} |
|
|
|
exercises.push({ |
|
name: exerciseName, |
|
isUnilateral, |
|
series |
|
}); |
|
} |
|
|
|
|
|
let totalTonnage = 0; |
|
exercises.forEach(exercise => { |
|
exercise.series.forEach(series => { |
|
|
|
const weightFactor = exercise.isUnilateral ? 2 : 1; |
|
totalTonnage += series.reps * series.weight * weightFactor; |
|
}); |
|
}); |
|
|
|
|
|
const workout = { |
|
id: currentWorkoutId || `workout-${Date.now()}`, |
|
name: workoutName, |
|
date: workoutDate, |
|
duration: workoutDuration, |
|
exercises, |
|
totalTonnage, |
|
satisfaction |
|
}; |
|
|
|
|
|
if (currentWorkoutId) { |
|
|
|
const index = workouts.findIndex(w => w.id === currentWorkoutId); |
|
if (index !== -1) { |
|
workouts[index] = workout; |
|
} |
|
} else { |
|
|
|
workouts.push(workout); |
|
} |
|
|
|
|
|
saveWorkouts(); |
|
|
|
|
|
showPage('home-page'); |
|
renderWorkoutsList(); |
|
} |
|
|
|
|
|
function renderWorkoutsList() { |
|
|
|
workoutsList.innerHTML = ''; |
|
|
|
|
|
if (workouts.length === 0) { |
|
emptyWorkoutMessage.classList.remove('hidden'); |
|
return; |
|
} |
|
|
|
emptyWorkoutMessage.classList.add('hidden'); |
|
|
|
|
|
const sortedWorkouts = [...workouts].sort((a, b) => { |
|
return new Date(b.date) - new Date(a.date); |
|
}); |
|
|
|
|
|
sortedWorkouts.forEach(workout => { |
|
const workoutDate = new Date(workout.date).toLocaleDateString('fr-FR'); |
|
const workoutDiv = document.createElement('div'); |
|
workoutDiv.className = 'card workout-card'; |
|
workoutDiv.setAttribute('data-workout-id', workout.id); |
|
|
|
workoutDiv.innerHTML = ` |
|
<div class="workout-header"> |
|
<h3>${workout.name}</h3> |
|
<div class="badge">${workoutDate}</div> |
|
</div> |
|
<div class="workout-details"> |
|
<p><strong>Durée:</strong> ${workout.duration} min</p> |
|
<p><strong>Exercices:</strong> ${workout.exercises.length}</p> |
|
<p><strong>Tonnage:</strong> ${workout.totalTonnage.toFixed(1)} kg</p> |
|
<p><strong>Satisfaction:</strong> ${workout.satisfaction}%</p> |
|
</div> |
|
`; |
|
|
|
|
|
workoutDiv.addEventListener('click', () => { |
|
displayWorkoutDetails(workout.id); |
|
}); |
|
|
|
workoutsList.appendChild(workoutDiv); |
|
}); |
|
|
|
|
|
updateStats(); |
|
} |
|
|
|
|
|
function displayWorkoutDetails(workoutId) { |
|
const workout = workouts.find(w => w.id === workoutId); |
|
if (!workout) return; |
|
|
|
|
|
document.getElementById('detail-workout-name').textContent = workout.name; |
|
document.getElementById('detail-date').textContent = new Date(workout.date).toLocaleDateString('fr-FR'); |
|
document.getElementById('detail-duration').textContent = workout.duration; |
|
document.getElementById('detail-tonnage').textContent = workout.totalTonnage.toFixed(1); |
|
document.getElementById('detail-satisfaction').textContent = `${workout.satisfaction}%`; |
|
document.getElementById('detail-exercises-count').textContent = workout.exercises.length; |
|
|
|
|
|
const exercisesContainer = document.getElementById('detail-exercises-container'); |
|
exercisesContainer.innerHTML = ''; |
|
|
|
workout.exercises.forEach(exercise => { |
|
const exerciseDiv = document.createElement('div'); |
|
exerciseDiv.className = 'card'; |
|
|
|
let seriesHtml = ''; |
|
exercise.series.forEach(series => { |
|
const degressiveLabel = series.isDegressive ? ' <span class="badge">Dégressive</span>' : ''; |
|
const weightFactor = exercise.isUnilateral ? 2 : 1; |
|
const seriesTonnage = series.reps * series.weight * weightFactor; |
|
|
|
seriesHtml += ` |
|
<div class="exercise-summary"> |
|
<div class="flex-between"> |
|
<span>${series.reps} répétitions × ${series.weight} kg${degressiveLabel}</span> |
|
<span>${seriesTonnage.toFixed(1)} kg</span> |
|
</div> |
|
</div> |
|
`; |
|
}); |
|
|
|
const unilateralLabel = exercise.isUnilateral ? ' <span class="badge">Unilatéral</span>' : ''; |
|
|
|
exerciseDiv.innerHTML = ` |
|
<h3>${exercise.name}${unilateralLabel}</h3> |
|
<div class="series-summary"> |
|
${seriesHtml} |
|
</div> |
|
`; |
|
|
|
exercisesContainer.appendChild(exerciseDiv); |
|
}); |
|
|
|
|
|
currentWorkoutId = workoutId; |
|
|
|
|
|
showPage('workout-details-page'); |
|
} |
|
|
|
|
|
function deleteWorkout() { |
|
if (!currentWorkoutId) return; |
|
|
|
const confirmDelete = confirm("Êtes-vous sûr de vouloir supprimer cette séance ?"); |
|
if (!confirmDelete) return |
|
|
|
|
|
|
|
if (!confirmDelete) return; |
|
|
|
|
|
workouts = workouts.filter(w => w.id !== currentWorkoutId); |
|
|
|
|
|
saveWorkouts(); |
|
|
|
|
|
showPage('home-page'); |
|
renderWorkoutsList(); |
|
} |
|
|
|
|
|
function clearNewWorkoutForm() { |
|
document.getElementById('workout-name').value = ''; |
|
document.getElementById('workout-duration').value = ''; |
|
setTodayDate(); |
|
exercisesContainer.innerHTML = ''; |
|
document.getElementById('satisfaction').value = 75; |
|
satisfactionValue.textContent = '75%'; |
|
} |
|
|
|
|
|
function updateStats() { |
|
if (workouts.length === 0) { |
|
document.getElementById('stats-workout-count').textContent = '0'; |
|
document.getElementById('stats-avg-tonnage').textContent = '0'; |
|
document.getElementById('stats-avg-satisfaction').textContent = '0%'; |
|
return; |
|
} |
|
|
|
|
|
document.getElementById('stats-workout-count').textContent = workouts.length; |
|
|
|
|
|
const totalTonnage = workouts.reduce((sum, workout) => sum + workout.totalTonnage, 0); |
|
const avgTonnage = totalTonnage / workouts.length; |
|
document.getElementById('stats-avg-tonnage').textContent = avgTonnage.toFixed(1); |
|
|
|
|
|
const totalSatisfaction = workouts.reduce((sum, workout) => sum + workout.satisfaction, 0); |
|
const avgSatisfaction = totalSatisfaction / workouts.length; |
|
document.getElementById('stats-avg-satisfaction').textContent = `${Math.round(avgSatisfaction)}%`; |
|
} |
|
</script> |
|
</body> |
|
</html> |