Compare commits

...

1 Commits
main ... v3.1.2

4 changed files with 49 additions and 15 deletions

4
.gitignore vendored
View File

@ -47,3 +47,7 @@ dist/
build/
.sass-cache/
.cache/
# --- Nginx erreurs fichiers ---
# A remplir au fur et à mesure
50x.html

View File

@ -12,8 +12,12 @@ et ce projet respecte le [Versionnement Sémantique](https://semver.org/lang/fr/
- **Moteur Drag & Drop Natif :** Implémentation d'un système de planification agile (Kanban) dans `app.js` permettant de glisser-déposer les séances d'entraînement à la souris sans aucune dépendance logicielle externe.
- **Cockpit Physiologique & Matériel :** Intégration de 4 indicateurs de performance (Fraîcheur VRC, Charge Hebdo, Usure Chaîne Vélo, Paires Carbone) basés sur des tracés SVG natifs et légers.
- **Gouvernance & Linters :** Déploiement des fichiers de configuration modernes `eslint.config.js` (Format Flat Config de niveau industriel) et `.stylelintrc.json` à la racine du projet.
- **Moteur Kanban Métier :** Implémentation du système de Drag & Drop natif dans l'onglet RYM Coach permettant de réorganiser le planning hebdomadaire.
- **Calculateur de Charge Dynamique :** Automatisation du recalcul du spinner "Charge Hebdo" en JavaScript à chaque déplacement d'entraînement.
### Modifié
- **Architecture de Navigation :** Consolidation du routage événementiel pour assurer la permutation étanche entre les onglets MCO Dashboard, RYM Bank, RYM Coach et Suivi Cohorte.
- **Design System :** Correction structurelle des imbrications de conteneurs Bootstrap 5 pour garantir un affichage fluide de la zone Expert.
- **Design System Responsif :** Optimisation de la structure Bootstrap 5 pour forcer l'alignement des "spinners" sur une seule ligne (`row`) sur écran desktop et une répartition fluide sur mobile.
- **Pont de Développement :** Restructuration du conteneur de validation openSUSE Leap 15.6 via un montage de volume Podman sécurisé (`:Z`) permettant l'audit du code en temps réel depuis l'hôte Fedora.

44
app.js
View File

@ -1,5 +1,5 @@
document.addEventListener("DOMContentLoaded", () => {
// --- GESTION DES ONGLETS EXISTANTE ---
// --- NAV SWITCHER DES ONGLETS LATÉRAUX ---
const navLinks = document.querySelectorAll(".nav-link");
const tabContents = document.querySelectorAll(".tab-content");
@ -11,21 +11,42 @@ document.addEventListener("DOMContentLoaded", () => {
link.classList.add("active");
const tabId = link.getAttribute("data-tab");
document.getElementById(tabId).classList.add("active");
const targetSection = document.getElementById(tabId);
if (targetSection) {
targetSection.classList.add("active");
}
});
});
// --- OPTION 1 : DRAG & DROP ENGINE (AAA SOUVERAIN) ---
// --- DRAG & DROP ENGINE INTELLIGENT ---
const draggables = document.querySelectorAll(".rym-draggable-workout");
const dropZones = document.querySelectorAll(".drop-zone");
function recalculerChargeHebdo() {
let totalSéances = 0;
dropZones.forEach(zone => {
totalSéances += zone.querySelectorAll(".rym-draggable-workout").length;
});
// Calcul dynamique : 25% de charge par bloc actif, plafonné à 100%
const nouvelleCharge = Math.min(totalSéances * 25, 100);
// Cibler le deuxième spinner du dashboard (Charge Hebdo)
const spinnerCharge = document.querySelectorAll(".rym-spinner-wrapper")[1];
if (spinnerCharge) {
const cercleStroke = spinnerCharge.querySelector(".circle-stroke");
const texteValeur = spinnerCharge.querySelector(".rym-spinner-text span");
texteValeur.textContent = nouvelleCharge;
cercleStroke.setAttribute("stroke-dasharray", `${nouvelleCharge}, 100`);
}
}
draggables.forEach(draggable => {
draggable.addEventListener("dragstart", (e) => {
e.dataTransfer.setData("text/plain", draggable.id);
// Petit délai pour l'effet visuel de déplacement
setTimeout(() => {
draggable.style.display = "none";
}, 0);
setTimeout(() => { draggable.style.display = "none"; }, 0);
});
draggable.addEventListener("dragend", () => {
@ -35,7 +56,7 @@ document.addEventListener("DOMContentLoaded", () => {
dropZones.forEach(zone => {
zone.addEventListener("dragover", (e) => {
e.preventDefault(); // Indispensable pour autoriser le drop
e.preventDefault();
zone.classList.add("drag-over");
});
@ -52,10 +73,11 @@ document.addEventListener("DOMContentLoaded", () => {
if (draggableElement) {
zone.appendChild(draggableElement);
// Ici se branchera l'appel API asynchrone vers ton Gitea/Serveur
const targetDay = zone.getAttribute("data-day");
console.log(`Séance déplacée avec succès sur le jour : ${targetDay}`);
recalculerChargeHebdo();
}
});
});
// Calcul initial
recalculerChargeHebdo();
});

View File

@ -135,7 +135,7 @@
<div class="col">
<div class="bg-light p-2 rounded border h-100 drop-zone" data-day="Lun">
<div class="fw-bold text-center border-bottom pb-1 mb-2 bg-dark text-white rounded-top small">Lundi</div>
<div class="rym-draggable-workout bg-primary text-white p-2 rounded mb-2 shadow-sm small" draggable="true" id="w1">
<div class="rym-draggable-workout bg-primary text-white p-2 rounded mb-2 shadow-sm small" draggable="true" id="w-swim">
<i class="bi bi-water me-1"></i> Natation : 2500m
</div>
</div>
@ -144,7 +144,7 @@
<div class="col">
<div class="bg-light p-2 rounded border h-100 drop-zone" data-day="Mar">
<div class="fw-bold text-center border-bottom pb-1 mb-2 bg-dark text-white rounded-top small">Mardi</div>
<div class="rym-draggable-workout bg-warning text-dark p-2 rounded mb-2 shadow-sm small" draggable="true" id="w2">
<div class="rym-draggable-workout bg-warning text-dark p-2 rounded mb-2 shadow-sm small" draggable="true" id="w-vma">
<i class="bi bi-lightning me-1"></i> VMA Balayage
</div>
</div>
@ -153,7 +153,7 @@
<div class="col">
<div class="bg-light p-2 rounded border h-100 drop-zone" data-day="Mer">
<div class="fw-bold text-center border-bottom pb-1 mb-2 bg-dark text-white rounded-top small">Mercredi</div>
<div class="rym-draggable-workout bg-info text-dark p-2 rounded mb-2 shadow-sm small" draggable="true" id="w3">
<div class="rym-draggable-workout bg-info text-dark p-2 rounded mb-2 shadow-sm small" draggable="true" id="w-bike">
<i class="bi bi-bicycle me-1"></i> Vélo Tempête
</div>
</div>
@ -186,7 +186,11 @@
</div>
</div>
<div class="card card-rym p-4 premium-zone shadow-lg">
<div class="card card-rym p-4 premium-zone shadow-lg mb-5">
<h5 class="fw-bold text-dark"><i class="bi bi-clock me-2"></i>Agenda Précision Premium</h5>
<p class="text-muted small mb-0">Zone réservée aux flux haute précision asynchrones.</p>
</div>
</section>
<section id="clients" class="tab-content">
<div class="d-flex justify-content-between align-items-center mb-4">