BitDown commited on
Commit
8be646c
·
verified ·
1 Parent(s): af41c81

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +75 -75
index.html CHANGED
@@ -27,9 +27,8 @@
27
  body { background-color: var(--bg-dark); color: var(--text-light); min-height: 100vh; padding-bottom: 80px; }
28
  .container { width: 100%; max-width: 800px; margin: 0 auto; padding: 1rem; }
29
  header { padding: 1rem 0; text-align: center; border-bottom: 1px solid var(--border-color); margin-bottom: 1rem; display: flex; flex-direction: column; align-items: center; }
30
- /* Style pour rendre le logo cliquable */
31
  #logo-link { display: inline-block; cursor: pointer; text-decoration: none; margin-bottom: 0.5rem; }
32
- header img#app-logo { max-width: 250px; height: auto; display: block; /* Assure que l'image est bien un bloc dans le lien */ }
33
  header p { color: var(--text-secondary); font-size: 0.9rem; }
34
  h1, h2, h3, h4 { font-family: var(--font-headings); font-weight: 700; color: var(--accent); text-transform: uppercase; letter-spacing: 0.5px; }
35
  .btn { background-color: var(--accent); color: var(--text-on-accent); border: none; padding: 0.6rem 1.2rem; border-radius: 4px; cursor: pointer; font-weight: bold; font-family: var(--font-headings); text-transform: uppercase; transition: background-color 0.2s, color 0.2s; }
@@ -114,10 +113,41 @@
114
  .type-trend-card li:last-child { border-bottom: none; }
115
  .type-trend-card li span:first-child { color: var(--text-secondary); font-size: 0.85rem; margin-right: 1rem; }
116
  .type-trend-card li strong { color: var(--accent); }
117
- /* Style simple pour la page d'accueil */
 
 
 
 
 
 
118
  #accueil-page .card p { line-height: 1.6; color: var(--text-light); }
119
- #accueil-page .card ul { list-style: disc; padding-left: 25px; margin-top: 1rem; color: var(--text-light); }
120
- #accueil-page .card li { margin-bottom: 0.5rem; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
  /* Media Queries */
123
  @media (max-width: 600px) {
@@ -176,18 +206,18 @@
176
  </div>
177
 
178
  <div id="app-container">
179
- <!-- *NOUVEAU* Accueil Page -->
180
  <div id="accueil-page">
181
  <h2>Bienvenue !</h2>
182
- <div class="card">
183
  <p>
184
- Bienvenue sur l'application de suivi de **Cocktail Fitness** !
185
  </p>
186
  <p style="margin-top: 1rem;">
187
  Utilisez cette application pour enregistrer vos séances d'entraînement,
188
  suivre votre progression et analyser vos performances au fil du temps.
189
  </p>
190
- <ul style="margin-top: 1rem;">
191
  <li>Cliquez sur "Séances" pour voir vos entraînements passés ou en créer un nouveau.</li>
192
  <li>Cliquez sur "Stats" pour visualiser vos statistiques globales.</li>
193
  <li>Gérez vos types de séances personnalisés (Push, Pull, Legs...).</li>
@@ -195,10 +225,12 @@
195
  <p style="margin-top: 1.5rem; text-align: center;">
196
  Bon entraînement ! 💪
197
  </p>
 
 
198
  </div>
199
  </div>
200
 
201
- <!-- *RENOMMÉ* Séances Page (Anciennement home-page) -->
202
  <div id="seances-page">
203
  <div class="flex-between">
204
  <h2>Mes séances</h2>
@@ -217,7 +249,6 @@
217
  <div id="manage-types-page">
218
  <div class="flex-between">
219
  <h2>Gérer les Types</h2>
220
- <!-- Bouton retour mène maintenant à la page des séances -->
221
  <button class="btn btn-outline back-to-seances-btn">Retour</button>
222
  </div>
223
  <div class="card">
@@ -241,7 +272,6 @@
241
  <div id="select-workout-type-page">
242
  <div class="flex-between">
243
  <h2>Démarrer Séance</h2>
244
- <!-- Bouton retour mène maintenant à la page des séances -->
245
  <button class="btn btn-outline back-to-seances-btn">Annuler</button>
246
  </div>
247
  <div class="card">
@@ -294,7 +324,6 @@
294
  <div id="workout-details-page">
295
  <div class="flex-between">
296
  <h2>Détail Séance <span id="detail-workout-type" class="badge type-badge hidden"></span></h2>
297
- <!-- Bouton retour mène maintenant à la page des séances -->
298
  <button class="btn btn-outline back-to-seances-btn">Retour</button>
299
  </div>
300
  <div class="card">
@@ -334,13 +363,10 @@
334
 
335
  </div> <!-- Fin #app-container -->
336
 
337
- <!-- Bottom Navigation - MISE A JOUR -->
338
  <nav class="nav-bottom">
339
- <!-- NOUVEAU lien Accueil -->
340
  <a href="#" class="nav-item" data-page="accueil-page"> <div class="nav-icon">🏠</div> <div>Accueil</div> </a>
341
- <!-- Lien Séances (anciennement Home) -->
342
  <a href="#" class="nav-item" data-page="seances-page"> <div class="nav-icon">📋</div> <div>Séances</div> </a>
343
- <!-- Lien Stats (inchangé) -->
344
  <a href="#" class="nav-item" data-page="stats-page"> <div class="nav-icon">📊</div> <div>Stats</div> </a>
345
  </nav>
346
 
@@ -369,7 +395,7 @@
369
  const authActionButton = document.getElementById('auth-action-btn');
370
  const authSwitchLink = document.getElementById('auth-switch-link');
371
  const forgotPasswordLink = document.getElementById('forgot-password-link');
372
- const logoLink = document.getElementById('logo-link'); // **NOUVEAU**
373
  const authTitle = document.getElementById('auth-title');
374
  const authSwitchText = document.getElementById('auth-switch-text');
375
  const loginMessage = document.getElementById('login-message');
@@ -384,7 +410,7 @@
384
  const addExerciseBtn = document.getElementById('add-exercise-btn');
385
  const exercisesContainer = document.getElementById('exercises-container');
386
  const workoutsList = document.getElementById('workouts-list');
387
- const backToSeancesBtns = document.querySelectorAll('.back-to-seances-btn'); // **RENOMMÉ**
388
  const deleteWorkoutBtn = document.getElementById('delete-workout-btn');
389
  const satisfactionRange = document.getElementById('satisfaction');
390
  const satisfactionValue = document.querySelector('.satisfaction-value');
@@ -413,7 +439,6 @@
413
  const typeTrendsContainer = document.getElementById('type-trends-container');
414
  const noTrendsMessage = document.getElementById('no-trends-message');
415
  const trendsSpinner = document.getElementById('trends-spinner');
416
- // On garde une référence à la page d'accueil et aux séances pour clarté
417
  const accueilPage = document.getElementById('accueil-page');
418
  const seancesPage = document.getElementById('seances-page');
419
 
@@ -421,41 +446,29 @@
421
  // --- DÉFINITION DES FONCTIONS ---
422
  // ===========================================
423
 
424
- function showMessage(message, isError = true) { /* ... inchangé ... */ if (loginMessage) { loginMessage.textContent = message; loginMessage.className = isError ? 'error' : 'success'; loginMessage.style.display = 'block'; } }
425
- function clearMessage() { /* ... inchangé ... */ if (loginMessage) { loginMessage.textContent = ''; loginMessage.style.display = 'none'; } }
426
-
427
  function initAuthListener() { if (!auth) return; auth.onAuthStateChanged(user => { console.log("Auth state changed:", user ? user.uid : 'null'); currentFirebaseUser = user; if (user) { showApp(); } else { workouts = []; userWorkoutTypes = []; showLoginPage(); } }); }
428
- function showLoginPage() { /* ... inchangé ... */ if(loginPage) loginPage.style.display = 'block'; if(mainAppContent) mainAppContent.style.display = 'none'; isLoginMode = true; authSwitchMode(); }
429
-
430
- function showApp() {
431
- if (!currentFirebaseUser || !mainAppContent) { showLoginPage(); return; }
432
- console.log("Affichage App for user:", currentFirebaseUser.email);
433
- if(loginPage) loginPage.style.display = 'none';
434
- mainAppContent.style.display = 'block';
435
- if(currentUserDisplay) currentUserDisplay.textContent = currentFirebaseUser.email;
436
- setTodayDate();
437
- loadWorkouts(); // Charger les données en arrière plan
438
- loadWorkoutTypes();
439
- showPage('accueil-page'); // **MODIFIÉ** : Démarrer sur la page d'accueil
440
- }
441
-
442
- function handleAuthAction(event) { /* ... inchangé ... */ if (!auth || !authEmailInput || !authPasswordInput || !authActionButton) return; event.preventDefault(); const email = authEmailInput.value; const password = authPasswordInput.value; clearMessage(); if (!email || !password) { showMessage('Email et Mot de passe requis.'); return; } authActionButton.disabled = true; authActionButton.textContent = 'Chargement...'; if (isLoginMode) { auth.signInWithEmailAndPassword(email, password).catch(handleAuthError).finally(() => { authActionButton.disabled = false; authActionButton.textContent = 'Se Connecter'; }); } else { auth.createUserWithEmailAndPassword(email, password).catch(handleAuthError).finally(() => { authActionButton.disabled = false; authActionButton.textContent = 'S\'inscrire'; }); } }
443
- function handlePasswordReset(event) { /* ... inchangé ... */ event.preventDefault(); if (!auth) { alert("Service d'authentification non disponible."); return; } clearMessage(); const email = prompt("Veuillez entrer votre adresse email pour recevoir le lien de réinitialisation :"); if (!email) { showMessage("Saisie de l'email annulée.", true); return; } console.log("Tentative d'envoi de l'email de réinitialisation à :", email); auth.sendPasswordResetEmail(email).then(() => { console.log("Email de réinitialisation envoyé."); showMessage("Si un compte existe pour " + email + ", un email de réinitialisation a été envoyé.", false); }).catch((error) => { console.error("Erreur sendPasswordResetEmail:", error); handleAuthError(error); }); }
444
- function handleLogout() { /* ... inchangé ... */ if (!auth) return; console.log("Déconnexion..."); auth.signOut().catch(error => { console.error("Logout Error:", error); alert("Erreur lors de la déconnexion."); }); }
445
- function authSwitchMode() { /* ... inchangé ... */ isLoginMode = !isLoginMode; clearMessage(); if (authEmailInput) authEmailInput.value = ''; if (authPasswordInput) authPasswordInput.value = ''; if (authTitle) authTitle.textContent = isLoginMode ? 'Connexion' : 'Inscription'; if (authActionButton) authActionButton.textContent = isLoginMode ? 'Se Connecter' : 'S\'inscrire'; if (authSwitchText) authSwitchText.textContent = isLoginMode ? 'Pas encore de compte ?' : 'Déjà un compte ?'; if (authSwitchLink) authSwitchLink.textContent = isLoginMode ? 'Inscrivez-vous ici' : 'Connectez-vous ici'; if (authEmailInput) authEmailInput.focus(); }
446
- function handleAuthError(error) { /* ... inchangé ... */ console.error("Erreur Auth Firebase:", error.code, error.message); showMessage(getAuthErrorMessage(error), true); }
447
- function getAuthErrorMessage(error) { /* ... inchangé ... */ switch (error.code) { case 'auth/invalid-email': return 'Format d\'email invalide.'; case 'auth/user-disabled': return 'Ce compte utilisateur a été désactivé.'; case 'auth/user-not-found': return 'Aucun utilisateur trouvé avec cet email.'; case 'auth/wrong-password': return 'Mot de passe incorrect.'; case 'auth/email-already-in-use': return 'Cet email est déjà utilisé par un autre compte.'; case 'auth/weak-password': return 'Le mot de passe doit contenir au moins 6 caractères.'; case 'auth/operation-not-allowed': return 'Méthode de connexion non activée.'; case 'auth/missing-password': return 'Mot de passe manquant.'; case 'auth/missing-email': return 'Adresse email manquante.'; default: console.error("Unhandled Auth Error Code:", error.code); return `Erreur (${error.code}). Veuillez réessayer.`; } }
448
  function loadWorkoutTypes() { /* ... inchangé ... */ if (!currentFirebaseUser || !db || !typesSpinner) return; const userId = currentFirebaseUser.uid; console.log("Chargement types pour", userId); userWorkoutTypes = []; typesSpinner.classList.remove('hidden'); db.collection('workoutTypes').where('userId', '==', userId).orderBy('name').get().then(snapshot => { userWorkoutTypes = []; snapshot.forEach(doc => { userWorkoutTypes.push({ id: doc.id, ...doc.data() }); }); console.log("Types chargés:", userWorkoutTypes); renderWorkoutTypesList(); populateWorkoutTypeSelector(); }).catch(handleFirestoreError).finally(() => { typesSpinner.classList.add('hidden'); }); }
449
  function renderWorkoutTypesList() { /* ... inchangé ... */ if (!workoutTypesList || !emptyTypesMessage) return; workoutTypesList.innerHTML = ''; if (userWorkoutTypes.length === 0) { emptyTypesMessage.classList.remove('hidden'); } else { emptyTypesMessage.classList.add('hidden'); userWorkoutTypes.forEach(type => { const li = document.createElement('li'); li.textContent = type.name; workoutTypesList.appendChild(li); }); } }
450
  function handleAddWorkoutType(event) { /* ... inchangé ... */ event.preventDefault(); if (!currentFirebaseUser || !newTypeNameInput || !db || !addTypeError || !addTypeForm) return; const typeName = newTypeNameInput.value.trim(); addTypeError.textContent = ''; addTypeError.style.display = 'none'; if (!typeName) { addTypeError.textContent = "Le nom du type ne peut pas être vide."; addTypeError.style.display = 'block'; return; } if (userWorkoutTypes.some(t => t.name.toLowerCase() === typeName.toLowerCase())) { addTypeError.textContent = "Ce type de séance existe déjà."; addTypeError.style.display = 'block'; return; } console.log("Ajout type:", typeName); const typeData = { userId: currentFirebaseUser.uid, name: typeName, createdAt: firebase.firestore.FieldValue.serverTimestamp() }; const addBtn = addTypeForm.querySelector('button'); if (addBtn) { addBtn.disabled = true; addBtn.textContent = '...'; } db.collection('workoutTypes').add(typeData).then(() => { console.log("Type ajouté avec succès"); newTypeNameInput.value = ''; loadWorkoutTypes(); }).catch(handleFirestoreError).finally(() => { if (addBtn) { addBtn.disabled = false; addBtn.textContent = 'Ajouter'; } }); }
451
  function populateWorkoutTypeSelector() { /* ... inchangé ... */ if (!selectWorkoutTypeDropdown) return; selectWorkoutTypeDropdown.innerHTML = '<option value="">-- Sélectionner Type --</option>'; userWorkoutTypes.forEach(type => { const option = document.createElement('option'); option.value = type.name; option.textContent = type.name; selectWorkoutTypeDropdown.appendChild(option); }); updateStartStructuredBtnState(); }
452
  function updateStartStructuredBtnState() { /* ... inchangé ... */ if (!selectWorkoutTypeDropdown || !startStructuredWorkoutBtn) return; startStructuredWorkoutBtn.disabled = !selectWorkoutTypeDropdown.value; }
453
- function loadWorkouts() { /* ... inchangé ... */ if (!currentFirebaseUser || !db || !spinner || !emptyWorkoutMessage || !workoutsList) { console.warn("Cannot load workouts: Missing user, db, or DOM elements."); if(workoutsList) workoutsList.innerHTML = ''; if(emptyWorkoutMessage) emptyWorkoutMessage.classList.remove('hidden'); workouts = []; updateStats(); return; } const userId = currentFirebaseUser.uid; console.log(`Chargement séances pour ${userId}...`); spinner.classList.remove('hidden'); emptyWorkoutMessage.classList.add('hidden'); workoutsList.innerHTML = ''; db.collection('workouts').where('userId', '==', userId).orderBy('date', 'desc').get().then((querySnapshot) => { workouts = []; console.log(`${querySnapshot.size} séances trouvées.`); querySnapshot.forEach((doc) => { const workoutData = doc.data(); workoutData.id = doc.id; workouts.push(workoutData); }); renderWorkoutsList(); updateStats(); }).catch(handleFirestoreError).finally(() => { spinner.classList.add('hidden'); if (workouts.length === 0) { emptyWorkoutMessage.classList.remove('hidden'); } }); }
454
- function saveWorkout() { /* ... inchangé ... */ if (!currentFirebaseUser || !db || !exercisesContainer || !saveWorkoutBtn) { alert("Erreur: Impossible de sauvegarder."); return; } const userId = currentFirebaseUser.uid; workoutExercisesForm = Array.from(exercisesContainer.querySelectorAll('.exercise')); const workoutNameInput = document.getElementById('workout-name'); const workoutName = workoutNameInput ? workoutNameInput.value.trim() : ''; const workoutDate = workoutDateInput ? workoutDateInput.value : ''; const workoutDurationInput = document.getElementById('workout-duration'); const workoutDuration = workoutDurationInput ? parseInt(workoutDurationInput.value) || 0 : 0; const satisfaction = satisfactionRange ? parseInt(satisfactionRange.value) : 75; if (!selectedWorkoutTypeName) { alert("Erreur interne: Type de séance manquant."); showPage('seances-page'); return; } if (!workoutDate) { alert("Veuillez sélectionner une date."); if(workoutDateInput) workoutDateInput.focus(); return; } if (workoutDuration <= 0) { alert("Veuillez entrer une durée valide (minutes)."); if(workoutDurationInput) workoutDurationInput.focus(); return; } if (workoutExercisesForm.length === 0) { alert("Veuillez ajouter au moins un exercice."); return; } const exercises = []; let validationError = null; workoutExercisesForm.forEach((exerciseEl, index) => { if (validationError) return; const nameInput = exerciseEl.querySelector('.exercise-name'); const exerciseName = nameInput ? nameInput.value.trim() : ''; const unilateralCheckbox = exerciseEl.querySelector('.unilateral-checkbox'); const isUnilateral = unilateralCheckbox ? unilateralCheckbox.checked : false; if (!exerciseName) { validationError = `Nommez l'exercice #${index + 1}.`; if(nameInput) nameInput.focus(); return; } const series = []; const seriesElements = exerciseEl.querySelectorAll('.series'); if (seriesElements.length === 0) { validationError = `L'exercice "${exerciseName}" n'a pas de série.`; return; } seriesElements.forEach((seriesEl, sIndex) => { if (validationError) return; const repsInput = seriesEl.querySelector('.reps'); const weightInput = seriesEl.querySelector('.weight'); const degressiveCheckbox = seriesEl.querySelector('.degressive-checkbox'); const reps = repsInput ? parseInt(repsInput.value) || 0 : 0; const weight = weightInput ? parseFloat(weightInput.value) || 0 : 0; const isDegressive = degressiveCheckbox ? degressiveCheckbox.checked : false; if (reps <= 0) { validationError = `Reps invalides pour série ${sIndex + 1} (${exerciseName}).`; if(repsInput) repsInput.focus(); return; } if (weight < 0) { validationError = `Charge invalide pour série ${sIndex + 1} (${exerciseName}).`; if(weightInput) weightInput.focus(); return; } series.push({ reps, weight, isDegressive }); }); if (!validationError) { exercises.push({ name: exerciseName, isUnilateral, series }); } }); if (validationError) { alert(validationError); return; } let totalTonnage = 0; exercises.forEach(ex => { (ex.series || []).forEach(s => { totalTonnage += (s.reps || 0) * (s.weight || 0) * (ex.isUnilateral ? 2 : 1); }); }); const finalWorkoutName = workoutName || selectedWorkoutTypeName; const workoutData = { userId: userId, workoutTypeName: selectedWorkoutTypeName, name: finalWorkoutName, date: workoutDate, duration: workoutDuration, exercises: exercises, totalTonnage: totalTonnage, satisfaction: satisfaction, lastUpdated: firebase.firestore.FieldValue.serverTimestamp() }; let savePromise; if (currentWorkoutId) { workoutData.createdAt = workouts.find(w => w.id === currentWorkoutId)?.createdAt || firebase.firestore.FieldValue.serverTimestamp(); savePromise = db.collection('workouts').doc(currentWorkoutId).set(workoutData); } else { workoutData.createdAt = firebase.firestore.FieldValue.serverTimestamp(); savePromise = db.collection('workouts').add(workoutData); } saveWorkoutBtn.disabled = true; saveWorkoutBtn.textContent = 'Sauvegarde...'; savePromise.then((docRefOrVoid) => { const savedId = currentWorkoutId || (docRefOrVoid ? docRefOrVoid.id : 'unknown'); console.log("Séance sauvegardée:", savedId); currentWorkoutId = null; try { if (typeof confetti === 'function') confetti({ particleCount: 150, spread: 90, origin: { y: 0.6 } }); } catch(e) { console.warn("Confetti error:", e)} showPage('seances-page'); loadWorkouts(); }).catch(handleFirestoreError).finally(() => { saveWorkoutBtn.disabled = false; saveWorkoutBtn.textContent = 'Enregistrer Séance'; }); }
455
- function deleteWorkout() { /* ... inchangé ... */ if (!currentFirebaseUser || !currentWorkoutId || !db || !deleteWorkoutBtn) return; const workoutToDelete = workouts.find(w => w && w.id === currentWorkoutId); if (!workoutToDelete) { console.error("Workout to delete not found locally."); return; } const confirmMsg = `Supprimer la séance "${workoutToDelete.name || 'Sans nom'}" du ${new Date(workoutToDelete.date).toLocaleDateString('fr-FR')} ?`; if (!confirm(confirmMsg)) return; console.log("Suppression séance:", currentWorkoutId); deleteWorkoutBtn.disabled = true; deleteWorkoutBtn.textContent = 'Suppression...'; db.collection('workouts').doc(currentWorkoutId).delete().then(() => { console.log("Séance supprimée avec succès:", currentWorkoutId); currentWorkoutId = null; showPage('seances-page'); loadWorkouts(); }).catch(handleFirestoreError).finally(() => { deleteWorkoutBtn.disabled = false; deleteWorkoutBtn.textContent = 'Supprimer Séance'; }); }
456
  function setTodayDate() { /* ... inchangé ... */ if (workoutDateInput) { try { const today = new Date(); const offset = today.getTimezoneOffset(); const localDate = new Date(today.getTime() - (offset*60*1000)); workoutDateInput.value = localDate.toISOString().split('T')[0]; } catch (e) { console.error("Erreur setTodayDate:", e); try { workoutDateInput.value = new Date().toISOString().split('T')[0]; } catch {} } } }
457
 
458
- function showPage(pageId) {
459
  if (!appContainer) { console.error("App container not found!"); return; }
460
  console.log(`Affichage page: ${pageId}`);
461
  const pages = appContainer.querySelectorAll(':scope > div[id$="-page"]');
@@ -465,41 +478,28 @@
465
  if (pageToShow) {
466
  pageToShow.classList.add('active');
467
  window.scrollTo(0, 0);
468
-
469
- // Page-specific actions
470
- if (pageId === 'new-workout-page') {
471
- if (!selectedWorkoutTypeName) {
472
- console.warn("Accès new-workout-page sans type.");
473
- alert("Veuillez sélectionner un type.");
474
- showPage('select-workout-type-page'); return;
475
- }
476
- renderActiveExerciseForm(); updateWorkoutTypeIndicator();
477
- } else if (pageId === 'manage-types-page') loadWorkoutTypes();
478
  else if (pageId === 'select-workout-type-page') populateWorkoutTypeSelector();
479
  else if (pageId === 'stats-page') updateStats();
480
- else if (pageId === 'workout-details-page' && !currentWorkoutId) {
481
- console.warn("Accès détails sans ID.");
482
- alert("Séance non spécifiée.");
483
- showPage('seances-page'); return;
484
- }
485
- // No specific action needed for 'accueil-page' or 'seances-page' here
486
-
487
  } else {
488
  console.error(`Page ID "${pageId}" non trouvée. Affichage accueil.`);
489
- if (accueilPage) accueilPage.classList.add('active'); // **MODIFIÉ** Fallback sur accueil
490
- pageId = 'accueil-page'; // Update pageId for nav highlighting
491
  }
492
 
493
- // Update bottom navigation highlighting
494
  navItems.forEach(item => item.classList.remove('active'));
495
- // Trouve le nav item correspondant à la page actuelle (accueil, seances, ou stats)
496
  const activeNavItem = document.querySelector(`.nav-item[data-page="${pageId}"]`);
497
  if (activeNavItem) {
498
  activeNavItem.classList.add('active');
499
  } else {
500
- // Si la page actuelle n'a pas de nav item direct (ex: détails), on active 'seances'
501
- const seancesNavItem = document.querySelector('.nav-item[data-page="seances-page"]');
502
- if(seancesNavItem) seancesNavItem.classList.add('active');
503
  }
504
  }
505
 
@@ -517,6 +517,7 @@
517
  function renderTypeTrends(trends) { /* ... inchangé ... */ if (!typeTrendsContainer || !noTrendsMessage || !trendsSpinner) { console.error("Cannot render trends: Missing DOM elements."); return;} trendsSpinner.classList.add('hidden'); typeTrendsContainer.innerHTML = ''; const trendTypes = Object.keys(trends); if (trendTypes.length === 0) { noTrendsMessage.classList.remove('hidden'); } else { noTrendsMessage.classList.add('hidden'); trendTypes.sort().forEach(typeName => { const typeData = trends[typeName]; if (!typeData || typeData.length === 0) return; const card = document.createElement('div'); card.className = 'card type-trend-card'; let listItems = ''; typeData.forEach(session => { const formattedDate = session.date ? new Date(session.date).toLocaleDateString('fr-FR', { day: '2-digit', month: 'short' }) : '??'; const tonnageText = (session.tonnage !== undefined && session.tonnage !== null) ? `${session.tonnage.toFixed(1)} kg` : 'N/A'; listItems += `<li><span>${formattedDate}</span> <strong>${tonnageText}</strong></li>`; }); card.innerHTML = `<h4>${typeName} (3 Dernières)</h4><ul>${listItems}</ul>`; typeTrendsContainer.appendChild(card); }); } }
518
  function handleFirestoreError(error) { /* ... inchangé ... */ console.error("Erreur Firestore:", error.code, error.message); alert(`Erreur de base de données: ${error.message}`); }
519
 
 
520
  // --- ÉCOUTEURS D'ÉVÉNEMENTS ---
521
  function initEventListeners() {
522
  console.log("initEventListeners: Attachement...");
@@ -527,7 +528,7 @@
527
  if (authSwitchLink) authSwitchLink.addEventListener('click', authSwitchMode); else console.error("!authSwitchLink");
528
  if (forgotPasswordLink) forgotPasswordLink.addEventListener('click', handlePasswordReset); else console.error("!forgotPasswordLink");
529
  if (logoutBtn) logoutBtn.addEventListener('click', handleLogout); else console.error("!logoutBtn");
530
- // Nav
531
  navItems.forEach((item) => { if (item) item.addEventListener('click', (e) => { e.preventDefault(); const targetPageId = item.getAttribute('data-page'); if (!currentFirebaseUser && targetPageId !== 'login-page') { showLoginPage(); return; } if (targetPageId) showPage(targetPageId); }); else console.error(`!navItem`); });
532
  // Workout List Actions
533
  if (newWorkoutBtn) newWorkoutBtn.addEventListener('click', () => { if (!currentFirebaseUser) return; showPage('select-workout-type-page'); }); else console.error("!newWorkoutBtn");
@@ -539,10 +540,9 @@
539
  if (startStructuredWorkoutBtn) startStructuredWorkoutBtn.addEventListener('click', () => { if (selectWorkoutTypeDropdown) { const type = selectWorkoutTypeDropdown.value; if (type) { clearNewWorkoutForm(type); showPage('new-workout-page'); } else { alert("Veuillez sélectionner un type de séance."); } } }); else console.error("!startStructuredWorkoutBtn");
540
  if (startFreeWorkoutBtn) startFreeWorkoutBtn.addEventListener('click', () => { clearNewWorkoutForm("Libre"); showPage('new-workout-page'); }); else console.error("!startFreeWorkoutBtn");
541
  // General Nav (Retour) -> Va maintenant à seances-page
542
- backToSeancesBtns.forEach(btn => { if (btn) btn.addEventListener('click', () => showPage('seances-page')); else console.error("!backToSeancesBtn"); });
543
  // New Workout Actions
544
- if (cancelNewWorkoutBtn) cancelNewWorkoutBtn.addEventListener('click', () => { if (confirm("Annuler cette séance ? Les données non enregistrées seront perdues.")) showPage('seances-page'); }); // **MODIFIÉ** Retour vers les séances
545
- else console.error("!cancelNewWorkoutBtn");
546
  if (saveWorkoutBtn) saveWorkoutBtn.addEventListener('click', saveWorkout); else console.error("!saveWorkoutBtn");
547
  if (addExerciseBtn) addExerciseBtn.addEventListener('click', handleAddNewExercise); else console.error("!addExerciseBtn");
548
  // Exercise Nav
 
27
  body { background-color: var(--bg-dark); color: var(--text-light); min-height: 100vh; padding-bottom: 80px; }
28
  .container { width: 100%; max-width: 800px; margin: 0 auto; padding: 1rem; }
29
  header { padding: 1rem 0; text-align: center; border-bottom: 1px solid var(--border-color); margin-bottom: 1rem; display: flex; flex-direction: column; align-items: center; }
 
30
  #logo-link { display: inline-block; cursor: pointer; text-decoration: none; margin-bottom: 0.5rem; }
31
+ header img#app-logo { max-width: 250px; height: auto; display: block; }
32
  header p { color: var(--text-secondary); font-size: 0.9rem; }
33
  h1, h2, h3, h4 { font-family: var(--font-headings); font-weight: 700; color: var(--accent); text-transform: uppercase; letter-spacing: 0.5px; }
34
  .btn { background-color: var(--accent); color: var(--text-on-accent); border: none; padding: 0.6rem 1.2rem; border-radius: 4px; cursor: pointer; font-weight: bold; font-family: var(--font-headings); text-transform: uppercase; transition: background-color 0.2s, color 0.2s; }
 
113
  .type-trend-card li:last-child { border-bottom: none; }
114
  .type-trend-card li span:first-child { color: var(--text-secondary); font-size: 0.85rem; margin-right: 1rem; }
115
  .type-trend-card li strong { color: var(--accent); }
116
+
117
+ /* === NOUVEAUX STYLES === */
118
+ /* Style page d'accueil */
119
+ #accueil-page .card {
120
+ border: 2px solid var(--accent); /* Ajout bordure jaune */
121
+ background-color: #282828; /* Fond légèrement différent pour se démarquer */
122
+ }
123
  #accueil-page .card p { line-height: 1.6; color: var(--text-light); }
124
+ #accueil-page .card ul { list-style: none; /* Retrait puces */ padding-left: 0; margin-top: 1rem; color: var(--text-light); }
125
+ #accueil-page .card li { margin-bottom: 0.6rem; padding-left: 1.5rem; position: relative; }
126
+ /* Ajout d'une puce personnalisée jaune */
127
+ #accueil-page .card li::before {
128
+ content: '✓'; /* Ou un autre symbole comme •, → */
129
+ color: var(--accent);
130
+ font-weight: bold;
131
+ position: absolute;
132
+ left: 0;
133
+ top: 0;
134
+ }
135
+ /* Style flèche guide */
136
+ .guide-arrow {
137
+ text-align: center;
138
+ margin-top: 1.5rem;
139
+ font-size: 2.5rem; /* Taille de la flèche */
140
+ color: var(--accent);
141
+ animation: bounce 2s infinite; /* Ajoute une petite animation */
142
+ }
143
+ /* Animation pour la flèche */
144
+ @keyframes bounce {
145
+ 0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
146
+ 40% { transform: translateY(-10px); }
147
+ 60% { transform: translateY(-5px); }
148
+ }
149
+ /* === FIN NOUVEAUX STYLES === */
150
+
151
 
152
  /* Media Queries */
153
  @media (max-width: 600px) {
 
206
  </div>
207
 
208
  <div id="app-container">
209
+ <!-- Accueil Page MISE A JOUR -->
210
  <div id="accueil-page">
211
  <h2>Bienvenue !</h2>
212
+ <div class="card"> <!-- La bordure jaune sera appliquée par le CSS -->
213
  <p>
214
+ Bienvenue sur l'application de suivi de <strong>Cocktail Fitness</strong> !
215
  </p>
216
  <p style="margin-top: 1rem;">
217
  Utilisez cette application pour enregistrer vos séances d'entraînement,
218
  suivre votre progression et analyser vos performances au fil du temps.
219
  </p>
220
+ <ul>
221
  <li>Cliquez sur "Séances" pour voir vos entraînements passés ou en créer un nouveau.</li>
222
  <li>Cliquez sur "Stats" pour visualiser vos statistiques globales.</li>
223
  <li>Gérez vos types de séances personnalisés (Push, Pull, Legs...).</li>
 
225
  <p style="margin-top: 1.5rem; text-align: center;">
226
  Bon entraînement ! 💪
227
  </p>
228
+ <!-- Flèche guide ajoutée ici -->
229
+ <div class="guide-arrow">↓</div>
230
  </div>
231
  </div>
232
 
233
+ <!-- Séances Page -->
234
  <div id="seances-page">
235
  <div class="flex-between">
236
  <h2>Mes séances</h2>
 
249
  <div id="manage-types-page">
250
  <div class="flex-between">
251
  <h2>Gérer les Types</h2>
 
252
  <button class="btn btn-outline back-to-seances-btn">Retour</button>
253
  </div>
254
  <div class="card">
 
272
  <div id="select-workout-type-page">
273
  <div class="flex-between">
274
  <h2>Démarrer Séance</h2>
 
275
  <button class="btn btn-outline back-to-seances-btn">Annuler</button>
276
  </div>
277
  <div class="card">
 
324
  <div id="workout-details-page">
325
  <div class="flex-between">
326
  <h2>Détail Séance <span id="detail-workout-type" class="badge type-badge hidden"></span></h2>
 
327
  <button class="btn btn-outline back-to-seances-btn">Retour</button>
328
  </div>
329
  <div class="card">
 
363
 
364
  </div> <!-- Fin #app-container -->
365
 
366
+ <!-- Bottom Navigation -->
367
  <nav class="nav-bottom">
 
368
  <a href="#" class="nav-item" data-page="accueil-page"> <div class="nav-icon">🏠</div> <div>Accueil</div> </a>
 
369
  <a href="#" class="nav-item" data-page="seances-page"> <div class="nav-icon">📋</div> <div>Séances</div> </a>
 
370
  <a href="#" class="nav-item" data-page="stats-page"> <div class="nav-icon">📊</div> <div>Stats</div> </a>
371
  </nav>
372
 
 
395
  const authActionButton = document.getElementById('auth-action-btn');
396
  const authSwitchLink = document.getElementById('auth-switch-link');
397
  const forgotPasswordLink = document.getElementById('forgot-password-link');
398
+ const logoLink = document.getElementById('logo-link');
399
  const authTitle = document.getElementById('auth-title');
400
  const authSwitchText = document.getElementById('auth-switch-text');
401
  const loginMessage = document.getElementById('login-message');
 
410
  const addExerciseBtn = document.getElementById('add-exercise-btn');
411
  const exercisesContainer = document.getElementById('exercises-container');
412
  const workoutsList = document.getElementById('workouts-list');
413
+ const backToSeancesBtns = document.querySelectorAll('.back-to-seances-btn');
414
  const deleteWorkoutBtn = document.getElementById('delete-workout-btn');
415
  const satisfactionRange = document.getElementById('satisfaction');
416
  const satisfactionValue = document.querySelector('.satisfaction-value');
 
439
  const typeTrendsContainer = document.getElementById('type-trends-container');
440
  const noTrendsMessage = document.getElementById('no-trends-message');
441
  const trendsSpinner = document.getElementById('trends-spinner');
 
442
  const accueilPage = document.getElementById('accueil-page');
443
  const seancesPage = document.getElementById('seances-page');
444
 
 
446
  // --- DÉFINITION DES FONCTIONS ---
447
  // ===========================================
448
 
449
+ // (Les définitions des fonctions JavaScript sont ici - identiques à la version précédente, sauf mention contraire)
450
+ function showMessage(message, isError = true) { if (loginMessage) { loginMessage.textContent = message; loginMessage.className = isError ? 'error' : 'success'; loginMessage.style.display = 'block'; } }
451
+ function clearMessage() { if (loginMessage) { loginMessage.textContent = ''; loginMessage.style.display = 'none'; } }
452
  function initAuthListener() { if (!auth) return; auth.onAuthStateChanged(user => { console.log("Auth state changed:", user ? user.uid : 'null'); currentFirebaseUser = user; if (user) { showApp(); } else { workouts = []; userWorkoutTypes = []; showLoginPage(); } }); }
453
+ function showLoginPage() { if(loginPage) loginPage.style.display = 'block'; if(mainAppContent) mainAppContent.style.display = 'none'; isLoginMode = true; authSwitchMode(); }
454
+ function showApp() { if (!currentFirebaseUser || !mainAppContent) { showLoginPage(); return; } console.log("Affichage App for user:", currentFirebaseUser.email); if(loginPage) loginPage.style.display = 'none'; mainAppContent.style.display = 'block'; if(currentUserDisplay) currentUserDisplay.textContent = currentFirebaseUser.email; setTodayDate(); loadWorkouts(); loadWorkoutTypes(); showPage('accueil-page'); } // Démarre sur accueil
455
+ function handleAuthAction(event) { if (!auth || !authEmailInput || !authPasswordInput || !authActionButton) return; event.preventDefault(); const email = authEmailInput.value; const password = authPasswordInput.value; clearMessage(); if (!email || !password) { showMessage('Email et Mot de passe requis.'); return; } authActionButton.disabled = true; authActionButton.textContent = 'Chargement...'; if (isLoginMode) { auth.signInWithEmailAndPassword(email, password).catch(handleAuthError).finally(() => { authActionButton.disabled = false; authActionButton.textContent = 'Se Connecter'; }); } else { auth.createUserWithEmailAndPassword(email, password).catch(handleAuthError).finally(() => { authActionButton.disabled = false; authActionButton.textContent = 'S\'inscrire'; }); } } // Ne pas switcher après inscription réussie
456
+ function handlePasswordReset(event) { event.preventDefault(); if (!auth) { alert("Service d'authentification non disponible."); return; } clearMessage(); const email = prompt("Veuillez entrer votre adresse email pour recevoir le lien de réinitialisation :"); if (!email) { showMessage("Saisie de l'email annulée.", true); return; } console.log("Tentative d'envoi de l'email de réinitialisation à :", email); auth.sendPasswordResetEmail(email).then(() => { console.log("Email de réinitialisation envoyé."); showMessage("Si un compte existe pour " + email + ", un email de réinitialisation a été envoyé.", false); }).catch((error) => { console.error("Erreur sendPasswordResetEmail:", error); handleAuthError(error); }); }
457
+ function handleLogout() { if (!auth) return; console.log("Déconnexion..."); auth.signOut().catch(error => { console.error("Logout Error:", error); alert("Erreur lors de la déconnexion."); }); }
458
+ function authSwitchMode() { isLoginMode = !isLoginMode; clearMessage(); if (authEmailInput) authEmailInput.value = ''; if (authPasswordInput) authPasswordInput.value = ''; if (authTitle) authTitle.textContent = isLoginMode ? 'Connexion' : 'Inscription'; if (authActionButton) authActionButton.textContent = isLoginMode ? 'Se Connecter' : 'S\'inscrire'; if (authSwitchText) authSwitchText.textContent = isLoginMode ? 'Pas encore de compte ?' : 'Déjà un compte ?'; if (authSwitchLink) authSwitchLink.textContent = isLoginMode ? 'Inscrivez-vous ici' : 'Connectez-vous ici'; if (authEmailInput) authEmailInput.focus(); }
459
+ function handleAuthError(error) { console.error("Erreur Auth Firebase:", error.code, error.message); showMessage(getAuthErrorMessage(error), true); }
460
+ function getAuthErrorMessage(error) { switch (error.code) { case 'auth/invalid-email': return 'Format d\'email invalide.'; case 'auth/user-disabled': return 'Ce compte utilisateur a été désactivé.'; case 'auth/user-not-found': return 'Aucun utilisateur trouvé avec cet email.'; case 'auth/wrong-password': return 'Mot de passe incorrect.'; case 'auth/email-already-in-use': return 'Cet email est déjà utilisé.'; case 'auth/weak-password': return 'Le mot de passe doit faire au moins 6 caractères.'; case 'auth/operation-not-allowed': return 'Méthode de connexion non activée.'; case 'auth/missing-password': return 'Mot de passe manquant.'; case 'auth/missing-email': return 'Adresse email manquante.'; default: console.error("Unhandled Auth Error Code:", error.code); return `Erreur (${error.code}). Veuillez réessayer.`; } }
 
 
 
 
 
 
 
 
 
 
 
 
461
  function loadWorkoutTypes() { /* ... inchangé ... */ if (!currentFirebaseUser || !db || !typesSpinner) return; const userId = currentFirebaseUser.uid; console.log("Chargement types pour", userId); userWorkoutTypes = []; typesSpinner.classList.remove('hidden'); db.collection('workoutTypes').where('userId', '==', userId).orderBy('name').get().then(snapshot => { userWorkoutTypes = []; snapshot.forEach(doc => { userWorkoutTypes.push({ id: doc.id, ...doc.data() }); }); console.log("Types chargés:", userWorkoutTypes); renderWorkoutTypesList(); populateWorkoutTypeSelector(); }).catch(handleFirestoreError).finally(() => { typesSpinner.classList.add('hidden'); }); }
462
  function renderWorkoutTypesList() { /* ... inchangé ... */ if (!workoutTypesList || !emptyTypesMessage) return; workoutTypesList.innerHTML = ''; if (userWorkoutTypes.length === 0) { emptyTypesMessage.classList.remove('hidden'); } else { emptyTypesMessage.classList.add('hidden'); userWorkoutTypes.forEach(type => { const li = document.createElement('li'); li.textContent = type.name; workoutTypesList.appendChild(li); }); } }
463
  function handleAddWorkoutType(event) { /* ... inchangé ... */ event.preventDefault(); if (!currentFirebaseUser || !newTypeNameInput || !db || !addTypeError || !addTypeForm) return; const typeName = newTypeNameInput.value.trim(); addTypeError.textContent = ''; addTypeError.style.display = 'none'; if (!typeName) { addTypeError.textContent = "Le nom du type ne peut pas être vide."; addTypeError.style.display = 'block'; return; } if (userWorkoutTypes.some(t => t.name.toLowerCase() === typeName.toLowerCase())) { addTypeError.textContent = "Ce type de séance existe déjà."; addTypeError.style.display = 'block'; return; } console.log("Ajout type:", typeName); const typeData = { userId: currentFirebaseUser.uid, name: typeName, createdAt: firebase.firestore.FieldValue.serverTimestamp() }; const addBtn = addTypeForm.querySelector('button'); if (addBtn) { addBtn.disabled = true; addBtn.textContent = '...'; } db.collection('workoutTypes').add(typeData).then(() => { console.log("Type ajouté avec succès"); newTypeNameInput.value = ''; loadWorkoutTypes(); }).catch(handleFirestoreError).finally(() => { if (addBtn) { addBtn.disabled = false; addBtn.textContent = 'Ajouter'; } }); }
464
  function populateWorkoutTypeSelector() { /* ... inchangé ... */ if (!selectWorkoutTypeDropdown) return; selectWorkoutTypeDropdown.innerHTML = '<option value="">-- Sélectionner Type --</option>'; userWorkoutTypes.forEach(type => { const option = document.createElement('option'); option.value = type.name; option.textContent = type.name; selectWorkoutTypeDropdown.appendChild(option); }); updateStartStructuredBtnState(); }
465
  function updateStartStructuredBtnState() { /* ... inchangé ... */ if (!selectWorkoutTypeDropdown || !startStructuredWorkoutBtn) return; startStructuredWorkoutBtn.disabled = !selectWorkoutTypeDropdown.value; }
466
+ function loadWorkouts() { /* ... inchangé ... */ if (!currentFirebaseUser || !db || !spinner || !emptyWorkoutMessage || !workoutsList) { console.warn("Cannot load workouts"); if(workoutsList) workoutsList.innerHTML = ''; if(emptyWorkoutMessage) emptyWorkoutMessage.classList.remove('hidden'); workouts = []; updateStats(); return; } const userId = currentFirebaseUser.uid; console.log(`Chargement séances pour ${userId}...`); spinner.classList.remove('hidden'); emptyWorkoutMessage.classList.add('hidden'); workoutsList.innerHTML = ''; db.collection('workouts').where('userId', '==', userId).orderBy('date', 'desc').get().then((querySnapshot) => { workouts = []; console.log(`${querySnapshot.size} séances trouvées.`); querySnapshot.forEach((doc) => { const workoutData = doc.data(); workoutData.id = doc.id; workouts.push(workoutData); }); renderWorkoutsList(); updateStats(); }).catch(handleFirestoreError).finally(() => { spinner.classList.add('hidden'); if (workouts.length === 0) { emptyWorkoutMessage.classList.remove('hidden'); } }); }
467
+ function saveWorkout() { /* ... inchangé - mais redirection vers seances-page ... */ if (!currentFirebaseUser || !db || !exercisesContainer || !saveWorkoutBtn) { alert("Erreur: Impossible de sauvegarder."); return; } const userId = currentFirebaseUser.uid; workoutExercisesForm = Array.from(exercisesContainer.querySelectorAll('.exercise')); const workoutNameInput = document.getElementById('workout-name'); const workoutName = workoutNameInput ? workoutNameInput.value.trim() : ''; const workoutDate = workoutDateInput ? workoutDateInput.value : ''; const workoutDurationInput = document.getElementById('workout-duration'); const workoutDuration = workoutDurationInput ? parseInt(workoutDurationInput.value) || 0 : 0; const satisfaction = satisfactionRange ? parseInt(satisfactionRange.value) : 75; if (!selectedWorkoutTypeName) { alert("Erreur interne: Type de séance manquant."); showPage('seances-page'); return; } if (!workoutDate) { alert("Veuillez sélectionner une date."); if(workoutDateInput) workoutDateInput.focus(); return; } if (workoutDuration <= 0) { alert("Veuillez entrer une durée valide."); if(workoutDurationInput) workoutDurationInput.focus(); return; } if (workoutExercisesForm.length === 0) { alert("Veuillez ajouter au moins un exercice."); return; } const exercises = []; let validationError = null; workoutExercisesForm.forEach((exerciseEl, index) => { if (validationError) return; const nameInput = exerciseEl.querySelector('.exercise-name'); const exerciseName = nameInput ? nameInput.value.trim() : ''; const unilateralCheckbox = exerciseEl.querySelector('.unilateral-checkbox'); const isUnilateral = unilateralCheckbox ? unilateralCheckbox.checked : false; if (!exerciseName) { validationError = `Nommez l'exercice #${index + 1}.`; if(nameInput) nameInput.focus(); return; } const series = []; const seriesElements = exerciseEl.querySelectorAll('.series'); if (seriesElements.length === 0) { validationError = `L'exercice "${exerciseName}" n'a pas de série.`; return; } seriesElements.forEach((seriesEl, sIndex) => { if (validationError) return; const repsInput = seriesEl.querySelector('.reps'); const weightInput = seriesEl.querySelector('.weight'); const degressiveCheckbox = seriesEl.querySelector('.degressive-checkbox'); const reps = repsInput ? parseInt(repsInput.value) || 0 : 0; const weight = weightInput ? parseFloat(weightInput.value) || 0 : 0; const isDegressive = degressiveCheckbox ? degressiveCheckbox.checked : false; if (reps <= 0) { validationError = `Reps invalides pour série ${sIndex + 1} (${exerciseName}).`; if(repsInput) repsInput.focus(); return; } if (weight < 0) { validationError = `Charge invalide pour série ${sIndex + 1} (${exerciseName}).`; if(weightInput) weightInput.focus(); return; } series.push({ reps, weight, isDegressive }); }); if (!validationError) { exercises.push({ name: exerciseName, isUnilateral, series }); } }); if (validationError) { alert(validationError); return; } let totalTonnage = 0; exercises.forEach(ex => { (ex.series || []).forEach(s => { totalTonnage += (s.reps || 0) * (s.weight || 0) * (ex.isUnilateral ? 2 : 1); }); }); const finalWorkoutName = workoutName || selectedWorkoutTypeName; const workoutData = { userId: userId, workoutTypeName: selectedWorkoutTypeName, name: finalWorkoutName, date: workoutDate, duration: workoutDuration, exercises: exercises, totalTonnage: totalTonnage, satisfaction: satisfaction, lastUpdated: firebase.firestore.FieldValue.serverTimestamp() }; let savePromise; if (currentWorkoutId) { workoutData.createdAt = workouts.find(w => w.id === currentWorkoutId)?.createdAt || firebase.firestore.FieldValue.serverTimestamp(); savePromise = db.collection('workouts').doc(currentWorkoutId).set(workoutData); } else { workoutData.createdAt = firebase.firestore.FieldValue.serverTimestamp(); savePromise = db.collection('workouts').add(workoutData); } saveWorkoutBtn.disabled = true; saveWorkoutBtn.textContent = 'Sauvegarde...'; savePromise.then((docRefOrVoid) => { const savedId = currentWorkoutId || (docRefOrVoid ? docRefOrVoid.id : 'unknown'); console.log("Séance sauvegardée:", savedId); currentWorkoutId = null; try { if (typeof confetti === 'function') confetti({ particleCount: 150, spread: 90, origin: { y: 0.6 } }); } catch(e) { console.warn("Confetti error:", e)} showPage('seances-page'); loadWorkouts(); }).catch(handleFirestoreError).finally(() => { saveWorkoutBtn.disabled = false; saveWorkoutBtn.textContent = 'Enregistrer Séance'; }); }
468
+ function deleteWorkout() { /* ... inchangé - mais redirection vers seances-page ... */ if (!currentFirebaseUser || !currentWorkoutId || !db || !deleteWorkoutBtn) return; const workoutToDelete = workouts.find(w => w && w.id === currentWorkoutId); if (!workoutToDelete) { console.error("Workout to delete not found locally."); return; } const confirmMsg = `Supprimer la séance "${workoutToDelete.name || 'Sans nom'}" du ${new Date(workoutToDelete.date).toLocaleDateString('fr-FR')} ?`; if (!confirm(confirmMsg)) return; console.log("Suppression séance:", currentWorkoutId); deleteWorkoutBtn.disabled = true; deleteWorkoutBtn.textContent = 'Suppression...'; db.collection('workouts').doc(currentWorkoutId).delete().then(() => { console.log("Séance supprimée avec succès:", currentWorkoutId); currentWorkoutId = null; showPage('seances-page'); loadWorkouts(); }).catch(handleFirestoreError).finally(() => { deleteWorkoutBtn.disabled = false; deleteWorkoutBtn.textContent = 'Supprimer Séance'; }); }
469
  function setTodayDate() { /* ... inchangé ... */ if (workoutDateInput) { try { const today = new Date(); const offset = today.getTimezoneOffset(); const localDate = new Date(today.getTime() - (offset*60*1000)); workoutDateInput.value = localDate.toISOString().split('T')[0]; } catch (e) { console.error("Erreur setTodayDate:", e); try { workoutDateInput.value = new Date().toISOString().split('T')[0]; } catch {} } } }
470
 
471
+ function showPage(pageId) { // **MODIFIÉ** pour gérer la nav d'accueil
472
  if (!appContainer) { console.error("App container not found!"); return; }
473
  console.log(`Affichage page: ${pageId}`);
474
  const pages = appContainer.querySelectorAll(':scope > div[id$="-page"]');
 
478
  if (pageToShow) {
479
  pageToShow.classList.add('active');
480
  window.scrollTo(0, 0);
481
+ // Actions spécifiques
482
+ if (pageId === 'new-workout-page') { if (!selectedWorkoutTypeName) { alert("Sélectionnez un type."); showPage('select-workout-type-page'); return; } renderActiveExerciseForm(); updateWorkoutTypeIndicator(); }
483
+ else if (pageId === 'manage-types-page') loadWorkoutTypes();
 
 
 
 
 
 
 
484
  else if (pageId === 'select-workout-type-page') populateWorkoutTypeSelector();
485
  else if (pageId === 'stats-page') updateStats();
486
+ else if (pageId === 'workout-details-page' && !currentWorkoutId) { alert("Séance non spécifiée."); showPage('seances-page'); return; }
 
 
 
 
 
 
487
  } else {
488
  console.error(`Page ID "${pageId}" non trouvée. Affichage accueil.`);
489
+ if (accueilPage) accueilPage.classList.add('active'); // Fallback sur accueil
490
+ pageId = 'accueil-page';
491
  }
492
 
493
+ // Mise à jour Nav Bottom
494
  navItems.forEach(item => item.classList.remove('active'));
495
+ // Active le bouton correspondant directement à la pageId si trouvé
496
  const activeNavItem = document.querySelector(`.nav-item[data-page="${pageId}"]`);
497
  if (activeNavItem) {
498
  activeNavItem.classList.add('active');
499
  } else {
500
+ // Si pas de bouton direct (ex: page détails), active "Séances" par défaut
501
+ const seancesNavItem = document.querySelector('.nav-item[data-page="seances-page"]');
502
+ if(seancesNavItem) seancesNavItem.classList.add('active');
503
  }
504
  }
505
 
 
517
  function renderTypeTrends(trends) { /* ... inchangé ... */ if (!typeTrendsContainer || !noTrendsMessage || !trendsSpinner) { console.error("Cannot render trends: Missing DOM elements."); return;} trendsSpinner.classList.add('hidden'); typeTrendsContainer.innerHTML = ''; const trendTypes = Object.keys(trends); if (trendTypes.length === 0) { noTrendsMessage.classList.remove('hidden'); } else { noTrendsMessage.classList.add('hidden'); trendTypes.sort().forEach(typeName => { const typeData = trends[typeName]; if (!typeData || typeData.length === 0) return; const card = document.createElement('div'); card.className = 'card type-trend-card'; let listItems = ''; typeData.forEach(session => { const formattedDate = session.date ? new Date(session.date).toLocaleDateString('fr-FR', { day: '2-digit', month: 'short' }) : '??'; const tonnageText = (session.tonnage !== undefined && session.tonnage !== null) ? `${session.tonnage.toFixed(1)} kg` : 'N/A'; listItems += `<li><span>${formattedDate}</span> <strong>${tonnageText}</strong></li>`; }); card.innerHTML = `<h4>${typeName} (3 Dernières)</h4><ul>${listItems}</ul>`; typeTrendsContainer.appendChild(card); }); } }
518
  function handleFirestoreError(error) { /* ... inchangé ... */ console.error("Erreur Firestore:", error.code, error.message); alert(`Erreur de base de données: ${error.message}`); }
519
 
520
+
521
  // --- ÉCOUTEURS D'ÉVÉNEMENTS ---
522
  function initEventListeners() {
523
  console.log("initEventListeners: Attachement...");
 
528
  if (authSwitchLink) authSwitchLink.addEventListener('click', authSwitchMode); else console.error("!authSwitchLink");
529
  if (forgotPasswordLink) forgotPasswordLink.addEventListener('click', handlePasswordReset); else console.error("!forgotPasswordLink");
530
  if (logoutBtn) logoutBtn.addEventListener('click', handleLogout); else console.error("!logoutBtn");
531
+ // Nav Bottom
532
  navItems.forEach((item) => { if (item) item.addEventListener('click', (e) => { e.preventDefault(); const targetPageId = item.getAttribute('data-page'); if (!currentFirebaseUser && targetPageId !== 'login-page') { showLoginPage(); return; } if (targetPageId) showPage(targetPageId); }); else console.error(`!navItem`); });
533
  // Workout List Actions
534
  if (newWorkoutBtn) newWorkoutBtn.addEventListener('click', () => { if (!currentFirebaseUser) return; showPage('select-workout-type-page'); }); else console.error("!newWorkoutBtn");
 
540
  if (startStructuredWorkoutBtn) startStructuredWorkoutBtn.addEventListener('click', () => { if (selectWorkoutTypeDropdown) { const type = selectWorkoutTypeDropdown.value; if (type) { clearNewWorkoutForm(type); showPage('new-workout-page'); } else { alert("Veuillez sélectionner un type de séance."); } } }); else console.error("!startStructuredWorkoutBtn");
541
  if (startFreeWorkoutBtn) startFreeWorkoutBtn.addEventListener('click', () => { clearNewWorkoutForm("Libre"); showPage('new-workout-page'); }); else console.error("!startFreeWorkoutBtn");
542
  // General Nav (Retour) -> Va maintenant à seances-page
543
+ backToSeancesBtns.forEach(btn => { if (btn) btn.addEventListener('click', () => showPage('seances-page')); else console.error("!backToSeancesBtn missing"); }); // **RENOMMÉ**
544
  // New Workout Actions
545
+ if (cancelNewWorkoutBtn) cancelNewWorkoutBtn.addEventListener('click', () => { if (confirm("Annuler cette séance ? Les données non enregistrées seront perdues.")) showPage('seances-page'); }); else console.error("!cancelNewWorkoutBtn");
 
546
  if (saveWorkoutBtn) saveWorkoutBtn.addEventListener('click', saveWorkout); else console.error("!saveWorkoutBtn");
547
  if (addExerciseBtn) addExerciseBtn.addEventListener('click', handleAddNewExercise); else console.error("!addExerciseBtn");
548
  // Exercise Nav