PAUTREL Johan commited on
Commit
a9f0fbf
·
verified ·
1 Parent(s): 89178ac

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +908 -19
index.html CHANGED
@@ -1,19 +1,908 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Track Lift - Suivi de Musculation</title>
7
+ <style>
8
+ :root {
9
+ --bg-dark: #121212;
10
+ --bg-card: #1e1e1e;
11
+ --text-light: #e0e0e0;
12
+ --accent: #4CAF50;
13
+ --accent-dark: #3a8a3d;
14
+ --danger: #f44336;
15
+ }
16
+
17
+ * {
18
+ margin: 0;
19
+ padding: 0;
20
+ box-sizing: border-box;
21
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
22
+ }
23
+
24
+ body {
25
+ background-color: var(--bg-dark);
26
+ color: var(--text-light);
27
+ min-height: 100vh;
28
+ padding-bottom: 80px; /* Pour le menu fixe en bas */
29
+ }
30
+
31
+ .container {
32
+ width: 100%;
33
+ max-width: 800px;
34
+ margin: 0 auto;
35
+ padding: 1rem;
36
+ }
37
+
38
+ header {
39
+ padding: 1rem 0;
40
+ text-align: center;
41
+ border-bottom: 1px solid #333;
42
+ margin-bottom: 1rem;
43
+ }
44
+
45
+ h1, h2, h3 {
46
+ color: var(--accent);
47
+ }
48
+
49
+ .btn {
50
+ background-color: var(--accent);
51
+ color: white;
52
+ border: none;
53
+ padding: 0.6rem 1.2rem;
54
+ border-radius: 4px;
55
+ cursor: pointer;
56
+ font-weight: bold;
57
+ transition: background-color 0.2s;
58
+ }
59
+
60
+ .btn:hover {
61
+ background-color: var(--accent-dark);
62
+ }
63
+
64
+ .btn-outline {
65
+ background-color: transparent;
66
+ color: var(--accent);
67
+ border: 1px solid var(--accent);
68
+ }
69
+
70
+ .btn-danger {
71
+ background-color: var(--danger);
72
+ }
73
+
74
+ input, select, textarea {
75
+ width: 100%;
76
+ padding: 0.6rem;
77
+ margin-bottom: 1rem;
78
+ background-color: #2a2a2a;
79
+ border: 1px solid #444;
80
+ border-radius: 4px;
81
+ color: var(--text-light);
82
+ }
83
+
84
+ input[type="checkbox"] {
85
+ width: auto;
86
+ margin-right: 0.5rem;
87
+ }
88
+
89
+ .card {
90
+ background-color: var(--bg-card);
91
+ border-radius: 8px;
92
+ padding: 1rem;
93
+ margin-bottom: 1rem;
94
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
95
+ }
96
+
97
+ .form-group {
98
+ margin-bottom: 1rem;
99
+ }
100
+
101
+ .form-row {
102
+ display: flex;
103
+ gap: 0.5rem;
104
+ margin-bottom: 0.5rem;
105
+ }
106
+
107
+ .form-row > * {
108
+ flex: 1;
109
+ margin-bottom: 0;
110
+ }
111
+
112
+ label {
113
+ display: block;
114
+ margin-bottom: 0.3rem;
115
+ color: #bbb;
116
+ }
117
+
118
+ .exercise {
119
+ border-left: 3px solid var(--accent);
120
+ padding-left: 1rem;
121
+ margin-bottom: 1.5rem;
122
+ }
123
+
124
+ .exercise-header {
125
+ display: flex;
126
+ justify-content: space-between;
127
+ align-items: center;
128
+ margin-bottom: 0.5rem;
129
+ }
130
+
131
+ .series-container {
132
+ margin-left: 0.5rem;
133
+ margin-top: 0.5rem;
134
+ }
135
+
136
+ .series {
137
+ background-color: #252525;
138
+ padding: 0.7rem;
139
+ border-radius: 4px;
140
+ margin-bottom: 0.5rem;
141
+ }
142
+
143
+ .nav-bottom {
144
+ position: fixed;
145
+ bottom: 0;
146
+ left: 0;
147
+ width: 100%;
148
+ background-color: #1a1a1a;
149
+ display: flex;
150
+ justify-content: space-around;
151
+ padding: 0.7rem 0;
152
+ box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.3);
153
+ }
154
+
155
+ .nav-item {
156
+ text-align: center;
157
+ color: #888;
158
+ text-decoration: none;
159
+ font-size: 0.85rem;
160
+ transition: color 0.2s;
161
+ }
162
+
163
+ .nav-item.active {
164
+ color: var(--accent);
165
+ }
166
+
167
+ .nav-icon {
168
+ font-size: 1.4rem;
169
+ margin-bottom: 0.2rem;
170
+ }
171
+
172
+ .workout-card {
173
+ border-left: 3px solid var(--accent);
174
+ cursor: pointer;
175
+ transition: transform 0.2s;
176
+ }
177
+
178
+ .workout-card:hover {
179
+ transform: translateX(5px);
180
+ }
181
+
182
+ .workout-header {
183
+ display: flex;
184
+ justify-content: space-between;
185
+ }
186
+
187
+ .stat-card {
188
+ text-align: center;
189
+ padding: 1rem;
190
+ }
191
+
192
+ .stat-value {
193
+ font-size: 1.8rem;
194
+ color: var(--accent);
195
+ font-weight: bold;
196
+ }
197
+
198
+ .stats-grid {
199
+ display: grid;
200
+ grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
201
+ gap: 1rem;
202
+ }
203
+
204
+ .hidden {
205
+ display: none;
206
+ }
207
+
208
+ #app-container > div {
209
+ display: none;
210
+ }
211
+
212
+ #app-container > div.active {
213
+ display: block;
214
+ }
215
+
216
+ .flex-between {
217
+ display: flex;
218
+ justify-content: space-between;
219
+ align-items: center;
220
+ }
221
+
222
+ .badge {
223
+ background-color: var(--accent);
224
+ color: white;
225
+ padding: 0.2rem 0.5rem;
226
+ border-radius: 10px;
227
+ font-size: 0.8rem;
228
+ }
229
+
230
+ .spinner {
231
+ border: 4px solid rgba(0, 0, 0, 0.1);
232
+ width: 36px;
233
+ height: 36px;
234
+ border-radius: 50%;
235
+ border-left-color: var(--accent);
236
+ animation: spin 1s linear infinite;
237
+ margin: 2rem auto;
238
+ display: none;
239
+ }
240
+
241
+ @keyframes spin {
242
+ 0% { transform: rotate(0deg); }
243
+ 100% { transform: rotate(360deg); }
244
+ }
245
+
246
+ .exercise-summary {
247
+ margin: 0.3rem 0;
248
+ padding: 0.3rem 0;
249
+ border-bottom: 1px solid #333;
250
+ }
251
+
252
+ .satisfaction {
253
+ display: flex;
254
+ align-items: center;
255
+ justify-content: center;
256
+ flex-direction: column;
257
+ margin-top: 1rem;
258
+ }
259
+
260
+ .satisfaction-value {
261
+ font-size: 2rem;
262
+ color: var(--accent);
263
+ margin-top: 0.5rem;
264
+ }
265
+
266
+ /* Pour les téléphones */
267
+ @media (max-width: 600px) {
268
+ .form-row {
269
+ flex-direction: column;
270
+ gap: 0;
271
+ }
272
+
273
+ .container {
274
+ padding: 0.5rem;
275
+ }
276
+
277
+ h1 {
278
+ font-size: 1.5rem;
279
+ }
280
+ }
281
+ </style>
282
+ </head>
283
+ <body>
284
+ <div class="container">
285
+ <header>
286
+ <h1>Track Lift</h1>
287
+ <p>Suivi de vos séances de musculation</p>
288
+ </header>
289
+
290
+ <div id="app-container">
291
+ <!-- Page d'accueil / Liste des séances -->
292
+ <div id="home-page" class="active">
293
+ <div class="flex-between">
294
+ <h2>Mes séances</h2>
295
+ <button id="new-workout-btn" class="btn">Nouvelle séance</button>
296
+ </div>
297
+
298
+ <div id="workouts-list" class="workout-list">
299
+ <!-- Liste des séances qui sera remplie dynamiquement -->
300
+ <div class="spinner"></div>
301
+ <p id="empty-workout-message" class="hidden" style="text-align: center; margin-top: 2rem;">
302
+ Aucune séance enregistrée. Créez votre première séance avec le bouton ci-dessus.
303
+ </p>
304
+ </div>
305
+ </div>
306
+
307
+ <!-- Page Nouvelle Séance -->
308
+ <div id="new-workout-page" class="hidden">
309
+ <div class="flex-between">
310
+ <h2>Nouvelle séance</h2>
311
+ <button id="save-workout-btn" class="btn">Enregistrer</button>
312
+ </div>
313
+
314
+ <div class="card">
315
+ <div class="form-group">
316
+ <label for="workout-name">Nom de la séance</label>
317
+ <input type="text" id="workout-name" placeholder="Ex: Push, Jambes, Full body...">
318
+ </div>
319
+
320
+ <div class="form-row">
321
+ <div class="form-group">
322
+ <label for="workout-date">Date</label>
323
+ <input type="date" id="workout-date">
324
+ </div>
325
+ <div class="form-group">
326
+ <label for="workout-duration">Durée (minutes)</label>
327
+ <input type="number" id="workout-duration" min="1" placeholder="60">
328
+ </div>
329
+ </div>
330
+ </div>
331
+
332
+ <h3 style="margin: 1rem 0;">Exercices</h3>
333
+ <div id="exercises-container">
334
+ <!-- Exercices ajoutés dynamiquement -->
335
+ </div>
336
+
337
+ <button id="add-exercise-btn" class="btn btn-outline" style="width: 100%; margin-top: 1rem;">
338
+ + Ajouter un exercice
339
+ </button>
340
+
341
+ <div class="card" style="margin-top: 2rem;">
342
+ <div class="form-group">
343
+ <label for="satisfaction">Niveau de satisfaction (1-100%)</label>
344
+ <input type="range" id="satisfaction" min="1" max="100" value="75">
345
+ <div class="satisfaction">
346
+ <span>Satisfaction</span>
347
+ <div class="satisfaction-value">75%</div>
348
+ </div>
349
+ </div>
350
+ </div>
351
+ </div>
352
+
353
+ <!-- Page Détail Séance -->
354
+ <div id="workout-details-page" class="hidden">
355
+ <div class="flex-between">
356
+ <h2 id="detail-workout-name">Détail de la séance</h2>
357
+ <button id="back-to-home" class="btn btn-outline">Retour</button>
358
+ </div>
359
+
360
+ <div class="card">
361
+ <div class="workout-details-info">
362
+ <div class="form-row">
363
+ <p><strong>Date:</strong> <span id="detail-date"></span></p>
364
+ <p><strong>Durée:</strong> <span id="detail-duration"></span> min</p>
365
+ </div>
366
+ </div>
367
+ </div>
368
+
369
+ <div class="stats-grid" style="margin-top: 1rem;">
370
+ <div class="card stat-card">
371
+ <div class="stat-value" id="detail-tonnage">0</div>
372
+ <div>Tonnage total (kg)</div>
373
+ </div>
374
+ <div class="card stat-card">
375
+ <div class="stat-value" id="detail-satisfaction">0%</div>
376
+ <div>Satisfaction</div>
377
+ </div>
378
+ <div class="card stat-card">
379
+ <div class="stat-value" id="detail-exercises-count">0</div>
380
+ <div>Exercices</div>
381
+ </div>
382
+ </div>
383
+
384
+ <h3 style="margin: 1.5rem 0 1rem;">Exercices réalisés</h3>
385
+ <div id="detail-exercises-container">
386
+ <!-- Exercices affichés dynamiquement -->
387
+ </div>
388
+
389
+ <button id="delete-workout-btn" class="btn btn-danger" style="width: 100%; margin-top: 2rem;">
390
+ Supprimer cette séance
391
+ </button>
392
+ </div>
393
+
394
+ <!-- Page Statistiques -->
395
+ <div id="stats-page" class="hidden">
396
+ <h2>Statistiques</h2>
397
+
398
+ <div class="stats-grid">
399
+ <div class="card stat-card">
400
+ <div class="stat-value" id="stats-workout-count">0</div>
401
+ <div>Séances totales</div>
402
+ </div>
403
+ <div class="card stat-card">
404
+ <div class="stat-value" id="stats-avg-tonnage">0</div>
405
+ <div>Tonnage moyen</div>
406
+ </div>
407
+ <div class="card stat-card">
408
+ <div class="stat-value" id="stats-avg-satisfaction">0%</div>
409
+ <div>Satisfaction moyenne</div>
410
+ </div>
411
+ </div>
412
+
413
+ <h3 style="margin: 1.5rem 0 1rem;">Dernières tendances</h3>
414
+ <div class="card">
415
+ <p style="text-align: center; margin: 1rem 0;">
416
+ Les statistiques détaillées seront calculées après plusieurs séances enregistrées.
417
+ </p>
418
+ </div>
419
+ </div>
420
+ </div>
421
+ </div>
422
+
423
+ <!-- Menu de navigation en bas -->
424
+ <nav class="nav-bottom">
425
+ <a href="#" class="nav-item active" data-page="home-page">
426
+ <div class="nav-icon">📋</div>
427
+ <div>Séances</div>
428
+ </a>
429
+ <a href="#" class="nav-item" data-page="stats-page">
430
+ <div class="nav-icon">📊</div>
431
+ <div>Stats</div>
432
+ </a>
433
+ </nav>
434
+
435
+ <script>
436
+ // Structure de données
437
+ let workouts = [];
438
+ const STORAGE_KEY = 'workout-tracker-data';
439
+
440
+ // Éléments DOM
441
+ const appContainer = document.getElementById('app-container');
442
+ const navItems = document.querySelectorAll('.nav-item');
443
+ const newWorkoutBtn = document.getElementById('new-workout-btn');
444
+ const saveWorkoutBtn = document.getElementById('save-workout-btn');
445
+ const addExerciseBtn = document.getElementById('add-exercise-btn');
446
+ const exercisesContainer = document.getElementById('exercises-container');
447
+ const workoutsList = document.getElementById('workouts-list');
448
+ const backToHomeBtn = document.getElementById('back-to-home');
449
+ const deleteWorkoutBtn = document.getElementById('delete-workout-btn');
450
+ const satisfactionRange = document.getElementById('satisfaction');
451
+ const satisfactionValue = document.querySelector('.satisfaction-value');
452
+ const emptyWorkoutMessage = document.getElementById('empty-workout-message');
453
+
454
+ // Variables globales
455
+ let currentWorkoutId = null;
456
+
457
+ // Initialisation
458
+ document.addEventListener('DOMContentLoaded', () => {
459
+ loadWorkouts();
460
+ renderWorkoutsList();
461
+ initEventListeners();
462
+ setTodayDate();
463
+ });
464
+
465
+ // Définir la date d'aujourd'hui par défaut
466
+ function setTodayDate() {
467
+ const today = new Date().toISOString().split('T')[0];
468
+ document.getElementById('workout-date').value = today;
469
+ }
470
+
471
+ // Charger les données depuis le stockage local
472
+ function loadWorkouts() {
473
+ const savedData = localStorage.getItem(STORAGE_KEY);
474
+ if (savedData) {
475
+ workouts = JSON.parse(savedData);
476
+ }
477
+ }
478
+
479
+ // Sauvegarder les données dans le stockage local
480
+ function saveWorkouts() {
481
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(workouts));
482
+ }
483
+
484
+ // Initialiser les événements
485
+ function initEventListeners() {
486
+ // Navigation
487
+ navItems.forEach(item => {
488
+ item.addEventListener('click', (e) => {
489
+ e.preventDefault();
490
+ const targetPage = item.getAttribute('data-page');
491
+
492
+ // Changer la page active
493
+ document.querySelectorAll('#app-container > div').forEach(page => {
494
+ page.classList.remove('active');
495
+ });
496
+ document.getElementById(targetPage).classList.add('active');
497
+
498
+ // Mettre à jour la navigation
499
+ navItems.forEach(navItem => navItem.classList.remove('active'));
500
+ item.classList.add('active');
501
+
502
+ // Si on va à la page statistiques, mettre à jour les stats
503
+ if (targetPage === 'stats-page') {
504
+ updateStats();
505
+ }
506
+ });
507
+ });
508
+
509
+ // Nouvelle séance
510
+ newWorkoutBtn.addEventListener('click', () => {
511
+ showPage('new-workout-page');
512
+ clearNewWorkoutForm();
513
+ currentWorkoutId = null;
514
+ });
515
+
516
+ // Enregistrer la séance
517
+ saveWorkoutBtn.addEventListener('click', saveWorkout);
518
+
519
+ // Ajouter un exercice
520
+ addExerciseBtn.addEventListener('click', addExercise);
521
+
522
+ // Retour à l'accueil
523
+ backToHomeBtn.addEventListener('click', () => {
524
+ showPage('home-page');
525
+ });
526
+
527
+ // Supprimer une séance
528
+ deleteWorkoutBtn.addEventListener('click', deleteWorkout);
529
+
530
+ // Affichage du pourcentage de satisfaction en temps réel
531
+ satisfactionRange.addEventListener('input', () => {
532
+ satisfactionValue.textContent = `${satisfactionRange.value}%`;
533
+ });
534
+ }
535
+
536
+ // Afficher une page spécifique
537
+ function showPage(pageId) {
538
+ document.querySelectorAll('#app-container > div').forEach(page => {
539
+ page.classList.remove('active');
540
+ });
541
+ document.getElementById(pageId).classList.add('active');
542
+
543
+ // Mettre à jour la navigation
544
+ const navItem = document.querySelector(`.nav-item[data-page="${pageId}"]`);
545
+ if (navItem) {
546
+ navItems.forEach(item => item.classList.remove('active'));
547
+ navItem.classList.add('active');
548
+ }
549
+ }
550
+
551
+ // Ajouter un exercice au formulaire
552
+ function addExercise() {
553
+ const exerciseId = `exercise-${Date.now()}`;
554
+ const exerciseDiv = document.createElement('div');
555
+ exerciseDiv.className = 'exercise card';
556
+ exerciseDiv.setAttribute('data-exercise-id', exerciseId);
557
+
558
+ exerciseDiv.innerHTML = `
559
+ <div class="exercise-header">
560
+ <input type="text" placeholder="Nom de l'exercice" class="exercise-name">
561
+ <button class="btn btn-danger remove-exercise" style="padding: 0.3rem 0.6rem;">×</button>
562
+ </div>
563
+ <div class="form-row">
564
+ <div class="form-group">
565
+ <label>
566
+ <input type="checkbox" class="unilateral-checkbox"> Exercice unilatéral
567
+ </label>
568
+ </div>
569
+ </div>
570
+ <div class="series-container">
571
+ <!-- Les séries seront ajoutées ici -->
572
+ </div>
573
+ <button class="btn btn-outline add-series" style="width: 100%; margin-top: 0.5rem;">
574
+ + Ajouter une série
575
+ </button>
576
+ `;
577
+
578
+ exercisesContainer.appendChild(exerciseDiv);
579
+
580
+ // Ajouter les écouteurs d'événements
581
+ const removeBtn = exerciseDiv.querySelector('.remove-exercise');
582
+ removeBtn.addEventListener('click', () => {
583
+ exerciseDiv.remove();
584
+ });
585
+
586
+ const addSeriesBtn = exerciseDiv.querySelector('.add-series');
587
+ addSeriesBtn.addEventListener('click', () => {
588
+ addSeries(exerciseDiv.querySelector('.series-container'));
589
+ });
590
+
591
+ // Ajouter la première série automatiquement
592
+ addSeries(exerciseDiv.querySelector('.series-container'));
593
+ }
594
+
595
+ // Ajouter une série à un exercice
596
+ function addSeries(container) {
597
+ const seriesId = `series-${Date.now()}`;
598
+ const seriesDiv = document.createElement('div');
599
+ seriesDiv.className = 'series';
600
+ seriesDiv.setAttribute('data-series-id', seriesId);
601
+
602
+ seriesDiv.innerHTML = `
603
+ <div class="form-row">
604
+ <div class="form-group">
605
+ <label>Répétitions</label>
606
+ <input type="number" class="reps" min="1" placeholder="12">
607
+ </div>
608
+ <div class="form-group">
609
+ <label>Charge (kg)</label>
610
+ <input type="number" class="weight" min="0" step="0.5" placeholder="20">
611
+ </div>
612
+ <div class="form-group" style="flex: 0.5;">
613
+ <label>
614
+ <input type="checkbox" class="degressive-checkbox"> Série dégressive
615
+ </label>
616
+ </div>
617
+ <button class="btn btn-danger remove-series" style="align-self: flex-end; padding: 0.3rem 0.6rem; flex: 0.2;">×</button>
618
+ </div>
619
+ `;
620
+
621
+ container.appendChild(seriesDiv);
622
+
623
+ // Écouteur pour supprimer une série
624
+ const removeBtn = seriesDiv.querySelector('.remove-series');
625
+ removeBtn.addEventListener('click', () => {
626
+ seriesDiv.remove();
627
+ });
628
+ }
629
+
630
+ // Sauvegarder la séance
631
+ function saveWorkout() {
632
+ // Récupérer les données de base
633
+ const workoutName = document.getElementById('workout-name').value.trim();
634
+ const workoutDate = document.getElementById('workout-date').value;
635
+ const workoutDuration = parseInt(document.getElementById('workout-duration').value) || 0;
636
+ const satisfaction = parseInt(document.getElementById('satisfaction').value);
637
+
638
+ // Vérifier les données obligatoires
639
+ if (!workoutName) {
640
+ alert("Veuillez saisir un nom pour la séance");
641
+ return;
642
+ }
643
+
644
+ if (!workoutDate) {
645
+ alert("Veuillez saisir une date");
646
+ return;
647
+ }
648
+
649
+ if (workoutDuration <= 0) {
650
+ alert("Veuillez saisir une durée valide");
651
+ return;
652
+ }
653
+
654
+ // Récupérer les exercices
655
+ const exercises = [];
656
+ const exerciseElements = exercisesContainer.querySelectorAll('.exercise');
657
+
658
+ if (exerciseElements.length === 0) {
659
+ alert("Ajoutez au moins un exercice");
660
+ return;
661
+ }
662
+
663
+ for (const exerciseEl of exerciseElements) {
664
+ const exerciseName = exerciseEl.querySelector('.exercise-name').value.trim();
665
+ const isUnilateral = exerciseEl.querySelector('.unilateral-checkbox').checked;
666
+
667
+ if (!exerciseName) {
668
+ alert("Veuillez saisir un nom pour chaque exercice");
669
+ return;
670
+ }
671
+
672
+ // Récupérer les séries
673
+ const series = [];
674
+ const seriesElements = exerciseEl.querySelectorAll('.series');
675
+
676
+ if (seriesElements.length === 0) {
677
+ alert(`Ajoutez au moins une série à l'exercice "${exerciseName}"`);
678
+ return;
679
+ }
680
+
681
+ for (const seriesEl of seriesElements) {
682
+ const reps = parseInt(seriesEl.querySelector('.reps').value) || 0;
683
+ const weight = parseFloat(seriesEl.querySelector('.weight').value) || 0;
684
+ const isDegressive = seriesEl.querySelector('.degressive-checkbox').checked;
685
+
686
+ if (reps <= 0) {
687
+ alert(`Veuillez saisir un nombre de répétitions valide pour l'exercice "${exerciseName}"`);
688
+ return;
689
+ }
690
+
691
+ series.push({
692
+ reps,
693
+ weight,
694
+ isDegressive
695
+ });
696
+ }
697
+
698
+ exercises.push({
699
+ name: exerciseName,
700
+ isUnilateral,
701
+ series
702
+ });
703
+ }
704
+
705
+ // Calculer le tonnage total
706
+ let totalTonnage = 0;
707
+ exercises.forEach(exercise => {
708
+ exercise.series.forEach(series => {
709
+ // Si l'exercice est unilatéral, on multiplie par 2 le tonnage
710
+ const weightFactor = exercise.isUnilateral ? 2 : 1;
711
+ totalTonnage += series.reps * series.weight * weightFactor;
712
+ });
713
+ });
714
+
715
+ // Créer l'objet séance
716
+ const workout = {
717
+ id: currentWorkoutId || `workout-${Date.now()}`,
718
+ name: workoutName,
719
+ date: workoutDate,
720
+ duration: workoutDuration,
721
+ exercises,
722
+ totalTonnage,
723
+ satisfaction
724
+ };
725
+
726
+ // Ajouter ou mettre à jour la séance
727
+ if (currentWorkoutId) {
728
+ // Mise à jour d'une séance existante
729
+ const index = workouts.findIndex(w => w.id === currentWorkoutId);
730
+ if (index !== -1) {
731
+ workouts[index] = workout;
732
+ }
733
+ } else {
734
+ // Nouvelle séance
735
+ workouts.push(workout);
736
+ }
737
+
738
+ // Sauvegarder les données
739
+ saveWorkouts();
740
+
741
+ // Retourner à la liste des séances
742
+ showPage('home-page');
743
+ renderWorkoutsList();
744
+ }
745
+
746
+ // Afficher la liste des séances
747
+ function renderWorkoutsList() {
748
+ // Vider la liste
749
+ workoutsList.innerHTML = '';
750
+
751
+ // Afficher le message si pas de séances
752
+ if (workouts.length === 0) {
753
+ emptyWorkoutMessage.classList.remove('hidden');
754
+ return;
755
+ }
756
+
757
+ emptyWorkoutMessage.classList.add('hidden');
758
+
759
+ // Trier les séances par date (la plus récente en premier)
760
+ const sortedWorkouts = [...workouts].sort((a, b) => {
761
+ return new Date(b.date) - new Date(a.date);
762
+ });
763
+
764
+ // Générer le HTML pour chaque séance
765
+ sortedWorkouts.forEach(workout => {
766
+ const workoutDate = new Date(workout.date).toLocaleDateString('fr-FR');
767
+ const workoutDiv = document.createElement('div');
768
+ workoutDiv.className = 'card workout-card';
769
+ workoutDiv.setAttribute('data-workout-id', workout.id);
770
+
771
+ workoutDiv.innerHTML = `
772
+ <div class="workout-header">
773
+ <h3>${workout.name}</h3>
774
+ <div class="badge">${workoutDate}</div>
775
+ </div>
776
+ <div class="workout-details">
777
+ <p><strong>Durée:</strong> ${workout.duration} min</p>
778
+ <p><strong>Exercices:</strong> ${workout.exercises.length}</p>
779
+ <p><strong>Tonnage:</strong> ${workout.totalTonnage.toFixed(1)} kg</p>
780
+ <p><strong>Satisfaction:</strong> ${workout.satisfaction}%</p>
781
+ </div>
782
+ `;
783
+
784
+ // Ajouter l'écouteur pour afficher les détails
785
+ workoutDiv.addEventListener('click', () => {
786
+ displayWorkoutDetails(workout.id);
787
+ });
788
+
789
+ workoutsList.appendChild(workoutDiv);
790
+ });
791
+
792
+ // Mettre à jour les statistiques globales
793
+ updateStats();
794
+ }
795
+
796
+ // Afficher les détails d'une séance
797
+ function displayWorkoutDetails(workoutId) {
798
+ const workout = workouts.find(w => w.id === workoutId);
799
+ if (!workout) return;
800
+
801
+ // Mettre à jour les informations de base
802
+ document.getElementById('detail-workout-name').textContent = workout.name;
803
+ document.getElementById('detail-date').textContent = new Date(workout.date).toLocaleDateString('fr-FR');
804
+ document.getElementById('detail-duration').textContent = workout.duration;
805
+ document.getElementById('detail-tonnage').textContent = workout.totalTonnage.toFixed(1);
806
+ document.getElementById('detail-satisfaction').textContent = `${workout.satisfaction}%`;
807
+ document.getElementById('detail-exercises-count').textContent = workout.exercises.length;
808
+
809
+ // Afficher les exercices
810
+ const exercisesContainer = document.getElementById('detail-exercises-container');
811
+ exercisesContainer.innerHTML = '';
812
+
813
+ workout.exercises.forEach(exercise => {
814
+ const exerciseDiv = document.createElement('div');
815
+ exerciseDiv.className = 'card';
816
+
817
+ let seriesHtml = '';
818
+ exercise.series.forEach(series => {
819
+ const degressiveLabel = series.isDegressive ? ' <span class="badge">Dégressive</span>' : '';
820
+ const weightFactor = exercise.isUnilateral ? 2 : 1;
821
+ const seriesTonnage = series.reps * series.weight * weightFactor;
822
+
823
+ seriesHtml += `
824
+ <div class="exercise-summary">
825
+ <div class="flex-between">
826
+ <span>${series.reps} répétitions × ${series.weight} kg${degressiveLabel}</span>
827
+ <span>${seriesTonnage.toFixed(1)} kg</span>
828
+ </div>
829
+ </div>
830
+ `;
831
+ });
832
+
833
+ const unilateralLabel = exercise.isUnilateral ? ' <span class="badge">Unilatéral</span>' : '';
834
+
835
+ exerciseDiv.innerHTML = `
836
+ <h3>${exercise.name}${unilateralLabel}</h3>
837
+ <div class="series-summary">
838
+ ${seriesHtml}
839
+ </div>
840
+ `;
841
+
842
+ exercisesContainer.appendChild(exerciseDiv);
843
+ });
844
+
845
+ // Stocker l'ID pour les éditions/suppressions
846
+ currentWorkoutId = workoutId;
847
+
848
+ // Afficher la page
849
+ showPage('workout-details-page');
850
+ }
851
+
852
+ // Supprimer une séance
853
+ function deleteWorkout() {
854
+ if (!currentWorkoutId) return;
855
+
856
+ const confirmDelete = confirm("Êtes-vous sûr de vouloir supprimer cette séance ?");
857
+ if (!confirmDelete) return
858
+
859
+ // Continuation du script précédent
860
+
861
+ if (!confirmDelete) return;
862
+
863
+ // Filtrer la séance à supprimer
864
+ workouts = workouts.filter(w => w.id !== currentWorkoutId);
865
+
866
+ // Sauvegarder les données
867
+ saveWorkouts();
868
+
869
+ // Retourner à la liste des séances
870
+ showPage('home-page');
871
+ renderWorkoutsList();
872
+ }
873
+
874
+ // Effacer le formulaire de nouvelle séance
875
+ function clearNewWorkoutForm() {
876
+ document.getElementById('workout-name').value = '';
877
+ document.getElementById('workout-duration').value = '';
878
+ setTodayDate();
879
+ exercisesContainer.innerHTML = '';
880
+ document.getElementById('satisfaction').value = 75;
881
+ satisfactionValue.textContent = '75%';
882
+ }
883
+
884
+ // Mettre à jour les statistiques
885
+ function updateStats() {
886
+ if (workouts.length === 0) {
887
+ document.getElementById('stats-workout-count').textContent = '0';
888
+ document.getElementById('stats-avg-tonnage').textContent = '0';
889
+ document.getElementById('stats-avg-satisfaction').textContent = '0%';
890
+ return;
891
+ }
892
+
893
+ // Nombre total de séances
894
+ document.getElementById('stats-workout-count').textContent = workouts.length;
895
+
896
+ // Tonnage moyen
897
+ const totalTonnage = workouts.reduce((sum, workout) => sum + workout.totalTonnage, 0);
898
+ const avgTonnage = totalTonnage / workouts.length;
899
+ document.getElementById('stats-avg-tonnage').textContent = avgTonnage.toFixed(1);
900
+
901
+ // Satisfaction moyenne
902
+ const totalSatisfaction = workouts.reduce((sum, workout) => sum + workout.satisfaction, 0);
903
+ const avgSatisfaction = totalSatisfaction / workouts.length;
904
+ document.getElementById('stats-avg-satisfaction').textContent = `${Math.round(avgSatisfaction)}%`;
905
+ }
906
+ </script>
907
+ </body>
908
+ </html>