diff --git a/AppGCC/AppGCC/templates/challenges.html b/AppGCC/AppGCC/templates/challenges.html index e673d8cb2ecd6a7416609b9c1656186eb382e9bd..7c34ba7168bdce9eb82c6ae9500efe3397ea0c8c 100644 --- a/AppGCC/AppGCC/templates/challenges.html +++ b/AppGCC/AppGCC/templates/challenges.html @@ -7,6 +7,8 @@ <title>Mes DĂ©fis</title> <script src="https://cdn.tailwindcss.com"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet"> + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"> + <script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js"></script> </head> <body class="bg-[#dfdbec] flex flex-col items-center justify-between min-h-screen p-6"> @@ -41,17 +43,44 @@ <!-- Title --> <h2 class="text-3xl font-bold text-[#102564] text-center mb-6">Mes Challenges du Jour</h2> + + <p id="successMessage" class="hidden text-center text-xl font-semibold text-green-600 mb-4 animate-bounce"> + 🎊 Tous les dĂ©fis sont complĂ©tĂ©s ! Bravo ! + </p> + + <!-- Barre de progression --> + <div class="w-full bg-gray-200 rounded-full h-4 mb-6"> + <div id="progressBar" class="bg-[#102564] h-4 rounded-full transition-all duration-500" style="width: 0%"></div> + </div> - <!-- Challenge List --> + <!-- Challenge List and put the icon --> <ul class="space-y-4"> {% for challenge in challenges %} <li class="flex items-center justify-between p-4 bg-gray-100 rounded-lg shadow-lg hover:shadow-xl transition duration-300"> - <div class="flex flex-col"> - <span class="text-lg font-medium text-[#102564]">{{ challenge.description }}</span> - <span class="text-sm text-gray-500">Niveau: {{ challenge.level }}</span> - <span class="text-sm text-gray-500">Lieu: {{ challenge.lieu }}</span> - <span class="text-sm text-gray-500">Points: {{ challenge.points }}</span> + <div class="flex items-center space-x-4"> + <!-- Icon --> + <i class="fas fa-{{ challenge.icon }} text-2xl text-[#102564]"></i> + + <!-- Challenge content --> + <div class="flex flex-col"> + <div class="flex items-center space-x-2"> + <span class="text-lg font-medium text-[#102564]">{{ challenge.description }}</span> + + <!-- GĂ©nĂ©ration du chemin de l'image --> + <i class="fas fa-info-circle text-blue-500 cursor-pointer hidden" + aria-label="Voir une illustration du dĂ©fi" + id="info-icon-{{ challenge.id }}" + data-images="{% static 'img/activities/' %}{{ challenge.id }}.gif, {% static 'img/activities/' %}{{ challenge.id }}.jpg, {% static 'img/activities/' %}{{ challenge.id }}.png, {% static 'img/activities/' %}{{ challenge.id }}.webp" + onclick="showImage(this.getAttribute('data-image'))"> + </i> + </div> + <span class="text-sm text-gray-500">Niveau: {{ challenge.level }}</span> + <span class="text-sm text-gray-500">Lieu: {{ challenge.lieu }}</span> + <span class="text-sm text-gray-500">Points: {{ challenge.points }}</span> + </div> </div> + + <!-- Validate Button --> <button id="validate-btn-{{ challenge.id }}" onclick="completeChallenge('{{ challenge.id }}')" class="py-2 px-4 bg-[#102564] text-white font-semibold rounded-lg shadow-md hover:bg-[#000000] transition duration-300">Valider</button> </li> {% endfor %} @@ -81,9 +110,9 @@ <h2 class="text-xl font-bold text-[#102564] mb-4">Modifier le Profil</h2> <label class="block text-sm text-gray-700">Niveau de difficultĂ©</label> <select id="difficulty" class="w-full p-2 border rounded-lg mb-4"> - <option value="facile" {% if user_difficulty == "facile" %}selected{% endif %}>Facile</option> - <option value="moyen" {% if user_difficulty == "moyen" %}selected{% endif %}>Moyen</option> - <option value="difficile" {% if user_difficulty == "difficile" %}selected{% endif %}>Difficile</option> + <option value="Facile" {% if user_difficulty == "facile" %}selected{% endif %}>Facile</option> + <option value="Moyen" {% if user_difficulty == "moyen" %}selected{% endif %}>Moyen</option> + <option value="Difficile" {% if user_difficulty == "difficile" %}selected{% endif %}>Difficile</option> </select> <button onclick="saveProfileSettings()" class="w-full bg-[#102564] text-white py-2 rounded-lg hover:bg-[#000000] transition duration-300">Enregistrer</button> <button onclick="toggleProfilePopup()" class="w-full mt-2 bg-gray-300 py-2 rounded-lg hover:bg-gray-400 transition duration-300">Annuler</button> @@ -98,6 +127,12 @@ <button onclick="closeConfirmationMessage()" class="w-full mt-2 bg-gray-300 py-2 rounded-lg hover:bg-gray-400 transition duration-300">OK</button> </div> </div> + + <!-- Image Popup --> + <div id="imagePopup" class="hidden opacity-0 fixed inset-0 bg-black bg-opacity-75 flex justify-center items-center transition-opacity duration-300"> + <img id="popupImage" class="transform scale-95 transition duration-300 max-w-full max-h-full rounded-lg shadow-lg"> + <button onclick="hideImage()" class="absolute top-4 right-4 text-white text-3xl font-bold">×</button> + </div> <script> function toggleProfilePopup() { @@ -153,9 +188,12 @@ button.disabled = true; button.classList.remove("hover:bg-[#000000]"); button.classList.add("bg-green-500", "cursor-not-allowed"); + button.classList.add("animate-pulse"); + + updateProgressBar(); } addValidatedChallenge(challengeId); - document.getElementById("confirmationText").innerText = "(" + data.points + " points)"; + document.getElementById("confirmationText").innerText = `🎉 Bien jouĂ© ! Tu gagnes ${data.points} points !`; document.getElementById("confirmationMessage").classList.remove("hidden"); } else { alert(data.message); @@ -181,14 +219,112 @@ .then(data => { if (data.status == "success") { alert("Paramètres enregistrĂ©s avec succès"); + location.reload(); toggleProfilePopup(); } else { alert(data.message); } }); } + + document.addEventListener("DOMContentLoaded", function () { + document.querySelectorAll("i[id^='info-icon-']").forEach(function (icon) { + let basePath = icon.getAttribute("data-images").split(",")[0]; // RĂ©cupère le chemin de base (sans format) + let formats = [".gif", ".jpg", ".png", ".webp"]; // Liste des formats Ă tester + let found = false; + + for (let i = 0; i < formats.length; i++) { + if (found) break; // ArrĂŞter dès qu'on trouve une image existante + + let img = new Image(); + let imgSrc = basePath.replace(".gif", formats[i]); // Remplace l'extension par le bon format + img.src = imgSrc; + + img.onload = function () { + icon.setAttribute("data-image", imgSrc); // Stocke le bon format trouvĂ© + icon.classList.remove("hidden"); // Affiche l'icĂ´ne + found = true; // Marque l'image comme trouvĂ©e + }; + } + }); + }); + + function showImage(imageUrl) { + const popup = document.getElementById("imagePopup"); + const image = document.getElementById("popupImage"); + + image.src = imageUrl; + popup.classList.remove("hidden"); + + requestAnimationFrame(() => { + popup.classList.add("opacity-100"); + image.classList.remove("scale-95"); + image.classList.add("scale-100"); + }); + } + + function hideImage() { + const popup = document.getElementById("imagePopup"); + const image = document.getElementById("popupImage"); + + popup.classList.remove("opacity-100"); + popup.classList.add("opacity-0"); + + image.classList.remove("scale-100"); + image.classList.add("scale-95"); + + setTimeout(() => { + popup.classList.add("hidden"); + popup.classList.remove("opacity-0"); + popup.classList.add("opacity-100"); + }, 300); + } + + function updateProgressBar() { + const total = document.querySelectorAll("button[id^='validate-btn-']").length; + const validated = document.querySelectorAll("button[disabled]").length; + const percentage = Math.round((validated / total) * 100); + document.getElementById("progressBar").style.width = percentage + "%"; + + // 🎉 Lancer les confettis quand tout est complĂ©tĂ© + if (percentage === 100 && !window.confettiLaunched) { + launchConfetti(); + document.getElementById("successMessage").classList.remove("hidden"); + window.confettiLaunched = true; // Ă©vite de rejouer plusieurs fois + } + } + + function launchConfetti() { + confetti({ + particleCount: 150, + spread: 70, + origin: { y: 0.6 }, + }); + + // Optionnel : plusieurs salves pour effet waouh + setTimeout(() => confetti({ particleCount: 100, spread: 120, origin: { y: 0.4 } }), 400); + setTimeout(() => confetti({ particleCount: 80, spread: 100, origin: { y: 0.8 } }), 800); + } + + // 1. Fermer avec la touche Escape + document.addEventListener("keydown", function (event) { + if (event.key === "Escape") { + hideImage(); + } + }); + + // 2. Fermer en cliquant dans le fond (mais pas sur l'image) + document.getElementById("imagePopup").addEventListener("click", function (event) { + // Si on clique sur le fond (et pas sur l’image elle-mĂŞme) + if (event.target === this) { + hideImage(); + } + }); - window.onload = checkValidatedButtons; + window.onload = () => { + checkValidatedButtons(); + updateProgressBar(); + }; </script> </body> </html> diff --git a/AppGCC/AppGCC/views.py b/AppGCC/AppGCC/views.py index 6f6fe4a58c83d4e0252afb946593d0bb5bbf5a08..e43f1f9718557bb0bfa1155436387f14c6fcc49f 100644 --- a/AppGCC/AppGCC/views.py +++ b/AppGCC/AppGCC/views.py @@ -15,6 +15,8 @@ CSV_FILE = "scores.csv" USER_FILE = "users.csv" DIFFICULTY_FILE = "difficulties.csv" DAILY_CHALLENGE_FILE = "daily_challenges.csv" +CATEGORIES = ["Au bureau (poste)", "Au bureau (espaces communs)", "ExtĂ©rieur"] +LEVELS = ["Facile", "Moyen", "Difficile"] def init_csv(): if not os.path.exists(CSV_FILE): @@ -33,7 +35,6 @@ def init_user_csv(): ################# def login_view(request): - # se log ou bien crĂ©er un compte si l'utilisateur n'existe pas sans mot de passe if request.method == "POST": username = request.POST.get("username") team = request.POST.get("team") @@ -49,11 +50,10 @@ def login_view(request): def add_user_to_csv(username, django_user_id): - """Ajoute un utilisateur avec un ID Django dans le fichier 'users.csv'.""" - user_id = django_user_id # Utiliser l'ID Django + user_id = django_user_id with open(USER_FILE, 'a', newline='') as file: writer = csv.writer(file) - writer.writerow([user_id, username]) # Ajouter l'ID Django et le nom d'utilisateur + writer.writerow([user_id, username]) return user_id ################## @@ -69,23 +69,15 @@ def logout_view(request): ################## def ranking_view(request): - """Afficher le classement des scores avec les nom d'utilisateur.""" - # Lire les scores depuis le fichier CSV scores = read_scores() - - # Lire les utilisateurs depuis la base de donnĂ©es Django users = read_users() - - # Lire les Ă©quipes depuis la base de donnĂ©es Django teams, user_teams = read_teams() - - # CrĂ©er le classement en associant le score avec le nom d'utilisateur + ranking = [] for user_id, score in scores.items(): - if int(user_id) in users: # Associer le user_id avec l'utilisateur dans le dictionnaire + if int(user_id) in users: ranking.append({"username": users[int(user_id)], "score": score, "user_team": user_teams[int(user_id)] if user_teams[int(user_id)] else "No Team"}) - # Construire un dictionnaire pour les scores d'Ă©quipe team_scores = {} for entry in ranking: @@ -94,7 +86,6 @@ def ranking_view(request): team_scores[team] = 0 team_scores[team] += entry["score"] - # Convertir en liste pour le template team_ranking = [] for team, score in team_scores.items(): team_ranking.append({ @@ -104,31 +95,23 @@ def ranking_view(request): team_ranking = [team for team in team_ranking if team["team"] != "No Team"] - # Trier le classement par score (du plus Ă©levĂ© au plus bas) ranking.sort(key=lambda x: x['score'], reverse=True) team_ranking.sort(key=lambda x: x["score"], reverse=True) - - print(f"Classement: {ranking}") # Debug : Afficher le classement - # Passer le classement Ă la vue pour l'afficher return render(request, "ranking.html", {"ranking": ranking, "team_ranking": team_ranking}) def read_users(): - """Lire les utilisateurs depuis django""" users = {} for user in User.objects.all(): users[user.id] = user.username - print(f"Utilisateurs: {users}") return users def read_teams(): - """Lire les Ă©quipes depuis django""" teams = {} for user in User.objects.all(): teams[user.id] = user.last_name - print(f"Équipes: {teams}") return list(set(teams)), teams ##################### @@ -136,83 +119,65 @@ def read_teams(): ##################### def challenges_view(request): - # Redirection vers la page de login en cas de session non authentifiĂ© if not request.user.is_authenticated: return redirect("login") - user_id = request.session.get('user_id') # Utiliser l'ID stockĂ© en session - today = datetime.today().strftime('%Y-%m-%d') # RĂ©cupĂ©rer la date du jour - - # VĂ©rifier si l'utilisateur a dĂ©jĂ gĂ©nĂ©rĂ© ses dĂ©fis pour aujourd'hui - user_challenges = read_user_daily_challenges(user_id, today) + user_id = request.session.get('user_id') + + user_challenges = read_user_daily_challenges(user_id, get_today()) if user_challenges: - # Si les dĂ©fis existent dĂ©jĂ pour aujourd'hui, on les rĂ©cupère depuis le fichier selected_challenges = user_challenges - print(f"DĂ©fis rĂ©cupĂ©rĂ©s pour aujourd'hui: {len(selected_challenges)} dĂ©fis") else: - # Sinon, gĂ©nĂ©rer de nouveaux dĂ©fis pour cet utilisateur - print("Aucun dĂ©fi gĂ©nĂ©rĂ© pour aujourd'hui, gĂ©nĂ©ration de nouveaux dĂ©fis.") - selected_challenges = generate_daily_challenges(user_id) # GĂ©nĂ©rer et enregistrer de nouveaux dĂ©fis - - # Rechercher la difficultĂ© de l'user connectĂ© + selected_challenges = generate_daily_challenges(user_id) user_difficulty = get_user_difficulty(user_id) - print(f"DifficultĂ© de l'utilisateur {user_id}: {user_difficulty}") selected_challenges = read_challenges_from_ids(selected_challenges) - # Passer les dĂ©fis du jour Ă la vue return render(request, "challenges.html", {"challenges": selected_challenges, "user_difficulty": user_difficulty}) def get_user_difficulty(user_id): - """RĂ©cupĂ©rer la difficultĂ© de l'utilisateur Ă partir du fichier 'difficulties.csv'.""" - difficulty = "moyen" # Valeur par dĂ©faut + difficulty = "moyen" if os.path.exists(DIFFICULTY_FILE): with open(DIFFICULTY_FILE, "r", newline="", encoding="utf-8") as file: reader = csv.reader(file) for row in reader: - if len(row) >= 2 and row[0] == str(user_id): # VĂ©rifier l'ID utilisateur - difficulty = row[1] # RĂ©cupĂ©rer la difficultĂ© + if len(row) >= 2 and row[0] == str(user_id): + difficulty = row[1] break - return difficulty + return difficulty.capitalize() def read_user_daily_challenges(user_id, today): - """Lire les dĂ©fis du jour pour un utilisateur donnĂ© depuis le fichier daily_challenges.csv.""" user_challenges = [] if os.path.exists(DAILY_CHALLENGE_FILE): with open(DAILY_CHALLENGE_FILE, 'r', newline='', encoding='utf-8') as file: reader = csv.reader(file) for row in reader: if len(row) >= 3 and row[1] == str(user_id) and row[0] == today: - user_challenges = row[2:] # Extraire les IDs des dĂ©fis du jour + user_challenges = row[2:] break return user_challenges def generate_daily_challenges(user_id): - """GĂ©nère et enregistre les dĂ©fis du jour pour l'utilisateur.""" challenges = read_challenges() user_difficulty = get_user_difficulty(user_id) - user_difficulty = user_difficulty.capitalize() daily_challenges = [] - categories = ["Au bureau (poste)", "Au bureau (espaces communs)", "ExtĂ©rieur"] - random.shuffle(categories) # MĂ©langer les catĂ©gories + categories = CATEGORIES.copy() + random.shuffle(categories) for category in categories: challenges_in_category = [c for c in challenges[user_difficulty] if c["lieu"] == category] if challenges_in_category: challenge = random.choice(challenges_in_category) daily_challenges.append(challenge["id"]) - save_daily_challenges_to_csv(user_id, daily_challenges) # Enregistrer les dĂ©fis du jour + save_daily_challenges_to_csv(user_id, daily_challenges) return daily_challenges def save_daily_challenges_to_csv(user_id, challenge_ids): - """Sauvegarder les dĂ©fis du jour dans un fichier CSV""" - today = datetime.today().strftime('%Y-%m-%d') with open(DAILY_CHALLENGE_FILE, 'a', newline='', encoding='utf-8') as file: writer = csv.writer(file) - writer.writerow([today, user_id] + challenge_ids) + writer.writerow([get_today(), user_id] + challenge_ids) def update_score(user_id, points): - """Mettre Ă jour le score d'un utilisateur.""" scores = read_scores() if str(user_id) in scores: scores[str(user_id)] += points @@ -221,24 +186,23 @@ def update_score(user_id, points): with open(CSV_FILE, 'w', newline='') as file: writer = csv.writer(file) - writer.writerow(["user_id", "score"]) # En-tĂŞte + writer.writerow(["user_id", "score"]) for user_id, score in scores.items(): writer.writerow([user_id, score]) def complete_challenge(request): if request.method == "POST": challenge_id = request.POST.get("challenge_id") - user_id = request.session.get('user_id') # RĂ©cupĂ©rer l'ID utilisateur depuis la session + user_id = request.session.get('user_id') points = get_challenge_points(challenge_id) if points: - update_score(user_id, points) # Mettre Ă jour le score de l'utilisateur + update_score(user_id, points) return JsonResponse({"status": "success", "points": points}) return JsonResponse({"status": "error", "message": "Invalid request"}, status=400) def read_challenges(): - """Lire tous les dĂ©fis depuis un fichier CSV avec des colonnes sĂ©parĂ©es par des virgules.""" challenges = {"Facile": [], "Moyen": [], "Difficile": []} if os.path.exists("challenges.csv"): with open("challenges.csv", 'r', newline='', encoding='utf-8') as file: @@ -257,7 +221,6 @@ def read_challenges(): return challenges def read_challenges_from_ids(challenge_ids): - """RĂ©cupĂ©rer les dĂ©fis Ă partir de leurs IDs.""" challenges = read_challenges() selected_challenges = [] for level in challenges: @@ -267,7 +230,6 @@ def read_challenges_from_ids(challenge_ids): return selected_challenges def get_challenge_points(challenge_id): - """RĂ©cupĂ©rer les points associĂ©s Ă un dĂ©fi donnĂ©.""" challenges = read_challenges() for level in challenges: for challenge in challenges[level]: @@ -275,28 +237,30 @@ def get_challenge_points(challenge_id): return int(challenge["points"]) return None -@csrf_exempt -def update_difficulty(request): - if request.method == "POST": - user_id = request.session.get('user_id') - difficulty = request.POST.get("difficulty") - if difficulty in ["Facile", "Moyen", "Difficile"]: - save_user_difficulty(user_id, difficulty) - return JsonResponse({"status": "success"}) - return JsonResponse({"status": "error", "message": "Invalid request"}, status=400) - -##################### +################################## # Page de Mise Ă jour difficulty # -##################### +################################## @csrf_exempt def update_difficulty(request): + if request.method == "POST": user_id = request.session.get('user_id') difficulty = request.POST.get("difficulty") - if difficulty in ["facile", "moyen", "difficile"]: - # Save user difficulty in file or database + if difficulty in ["Facile", "Moyen", "Difficile"]: save_user_difficulty(user_id, difficulty) + today = get_today() + with open(DAILY_CHALLENGE_FILE, 'r', newline='', encoding='utf-8') as file: + reader = csv.reader(file) + data = [] + for row in reader: + if len(row) >= 3 and row[1] == str(user_id) and row[0] == today: + continue + data.append(row) + with open(DAILY_CHALLENGE_FILE, 'w', newline='', encoding='utf-8') as file: + writer = csv.writer(file) + for row in data: + writer.writerow(row) return JsonResponse({"status": "success"}) else: return JsonResponse({"status": "error", "message": "Invalid difficulty"}) @@ -312,14 +276,13 @@ def read_scores(): if os.path.exists(CSV_FILE): with open(CSV_FILE, 'r', newline='') as file: reader = csv.reader(file) - next(reader) # Ignorer l'en-tĂŞte + next(reader) for row in reader: if len(row) >= 2: - scores[row[0]] = int(row[1]) # Ajouter le score Ă un dictionnaire + scores[row[0]] = int(row[1]) return scores def save_user_difficulty(user_id, difficulty): - """Remplace si l'user Ă dĂ©jĂ sauvegarder sa difficultĂ© sinon sauvegarde la le tout dans un fichier CSV.""" data = [] if os.path.exists(DIFFICULTY_FILE): with open(DIFFICULTY_FILE, "r", newline="", encoding="utf-8") as file: @@ -336,3 +299,6 @@ def save_user_difficulty(user_id, difficulty): writer.writerow(row) if [user_id, difficulty] not in data: writer.writerow([user_id, difficulty]) + +def get_today(): + return datetime.today().strftime('%Y-%m-%d') diff --git a/AppGCC/challenges.csv b/AppGCC/challenges.csv new file mode 100644 index 0000000000000000000000000000000000000000..63d542b9e4f7ad91ea50afb29e0f60c542ff3f5b --- /dev/null +++ b/AppGCC/challenges.csv @@ -0,0 +1,45 @@ +1,Étirements des bras et Ă©paules (2 min),Facile,Au bureau (poste),5,arrows-up-down-left-right +2,Se tenir droit et contracter les abdos (5 min),Facile,Au bureau (poste),5,user +3,S'asseoir et se lever de sa chaise (10 fois),Facile,Au bureau (poste),5,circle-arrow-up +4,Tenir 30 sec en Ă©quilibre sur un pied,Facile,Au bureau (poste),5,universal-access +5,Rotations poignets et Ă©paules (1 min),Facile,Au bureau (poste),5,arrows-rotate +6,Prendre les escaliers toute la journĂ©e,Facile,Au bureau (espaces communs),10,stairs +7,Marcher 5000 pas dans la journĂ©e,Facile,Au bureau (espaces communs),10,shoe-prints +8,Marcher 5 min après chaque rĂ©union,Facile,Au bureau (espaces communs),10,clock +9,Flexions des genoux (10 fois),Facile,Au bureau (espaces communs),10,circle-arrow-down +10,Respiration profonde (5 fois),Facile,Au bureau (espaces communs),10,wind +11,Marche rapide (10 min) pause dĂ©jeuner,Facile,ExtĂ©rieur,15,person-walking +12,Descendre un arrĂŞt plus tĂ´t,Facile,ExtĂ©rieur,15,bus +13,Aller voir un collègue au lieu d’un e-mail,Facile,ExtĂ©rieur,15,envelope-open-text +14,Balade autour du bureau,Facile,ExtĂ©rieur,15,tree +15,20 montĂ©es de marches en extĂ©rieur,Facile,ExtĂ©rieur,15,stairs +16,10 squats sans quitter son bureau,Moyen,Au bureau (poste),5,person-running +17,Gainage sur chaise (30 sec),Moyen,Au bureau (poste),5,grip-lines +18,20 extensions de mollets,Moyen,Au bureau (poste),5,person-walking +19,30 contractions abdos assis,Moyen,Au bureau (poste),5,user +20,Alterner assis/debout toutes les 30 min (2h),Moyen,Au bureau (poste),5,clock +21,Escaliers 3 jours d’affilĂ©e,Moyen,Au bureau (espaces communs),10,stairs +22,Se lever et marcher 5 min toutes les heures,Moyen,Au bureau (espaces communs),10,clock +23,10 montĂ©es de marches,Moyen,Au bureau (espaces communs),10,stairs +24,15 squats en salle de repos,Moyen,Au bureau (espaces communs),10,dumbbell +25,10 rotations de chevilles assis,Moyen,Au bureau (espaces communs),10,arrows-rotate +26,Marche rapide (15 min),Moyen,ExtĂ©rieur,15,person-walking +27,10 flexions jambes en attendant mĂ©tro,Moyen,ExtĂ©rieur,15,bus +28,Aller au travail Ă pied/vĂ©lo (1x/semaine),Moyen,ExtĂ©rieur,15,person-biking +29,7500 pas dans la journĂ©e,Moyen,ExtĂ©rieur,15,shoe-prints +30,Balade de 20 min en fin de journĂ©e,Moyen,ExtĂ©rieur,15,tree +31,Gainage contre mur (1 min),Difficile,Au bureau (poste),5,grip-lines +32,20 squats en plusieurs fois,Difficile,Au bureau (poste),5,person-running +33,50 extensions de mollets,Difficile,Au bureau (poste),5,person-walking +34,Planche sur chaise (2 min),Difficile,Au bureau (poste),5,grip-lines +35,50 contractions abdos assis,Difficile,Au bureau (poste),5,user +36,Escaliers uniquement (5 jours consĂ©cutifs),Difficile,Au bureau (espaces communs),10,stairs +37,Marche 10 min après dĂ©jeuner (3 jours),Difficile,Au bureau (espaces communs),10,person-walking +38,DĂ©fi collectif avec 3 collègues,Difficile,Au bureau (espaces communs),10,users +39,Se lever et marcher toutes les 30 min,Difficile,Au bureau (espaces communs),10,clock +40,3 min de montĂ©es de genoux salle de repos,Difficile,Au bureau (espaces communs),10,person-running +41,10000 pas dans la journĂ©e,Difficile,ExtĂ©rieur,15,shoe-prints +42,Balade de 30 min après le travail,Difficile,ExtĂ©rieur,15,tree +43,Aller au travail Ă vĂ©lo (3x/semaine),Difficile,ExtĂ©rieur,15,person-biking +44,Marcher/courir 5 km en dehors du bureau,Difficile,ExtĂ©rieur,15,shoe-prints +45,SĂ©ance collective sportive extĂ©rieure,Difficile,ExtĂ©rieur,15,users diff --git a/AppGCC/daily_challenges.csv b/AppGCC/daily_challenges.csv new file mode 100644 index 0000000000000000000000000000000000000000..e0f808cba924fe44e31c3d45ff19c6275541192b --- /dev/null +++ b/AppGCC/daily_challenges.csv @@ -0,0 +1,7 @@ +2025-03-21,33,27,21,20 +2025-03-21,34,20,26,23 +2025-03-21,23,17,30,23 +2025-03-21,40,21,29,17 +2025-03-21,41,26,17,25 +2025-03-21,42,20,23,28 +2025-03-21,43,17,28,25 diff --git a/AppGCC/db.sqlite3 b/AppGCC/db.sqlite3 index acabd13d0d321122a99c005ae2e753e2b29ab9e5..a5af0197f11db804307cf0c42f48910491ada112 100644 Binary files a/AppGCC/db.sqlite3 and b/AppGCC/db.sqlite3 differ diff --git a/AppGCC/difficulties.csv b/AppGCC/difficulties.csv new file mode 100644 index 0000000000000000000000000000000000000000..02c307ca5b546549e2e670a1a6d1ddf564b89658 --- /dev/null +++ b/AppGCC/difficulties.csv @@ -0,0 +1,8 @@ +2,difficile +17,difficile +22,difficile +35,facile +34,moyen +39,facile +23,moyen +41,Moyen diff --git a/AppGCC/scores.csv b/AppGCC/scores.csv new file mode 100644 index 0000000000000000000000000000000000000000..16ef85f56b6be65be4dedfa6dfd6c728b9d35a9d --- /dev/null +++ b/AppGCC/scores.csv @@ -0,0 +1,28 @@ +user_id,score +2,49 +17,10 +18,26 +19,36 +20,75 +21,60 +1,50 +22,135 +23,196 +24,22 +25,12 +26,5 +27,20 +28,15 +29,15 +30,30 +31,30 +32,25 +34,50 +35,30 +37,40 +38,30 +39,15 +40,30 +41,55 +42,30 +43,15 diff --git a/AppGCC/static/img/activities/1.gif b/AppGCC/static/img/activities/1.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b02c05643d6bf6af2e30e3b15d85bddabcc0304 Binary files /dev/null and b/AppGCC/static/img/activities/1.gif differ diff --git a/AppGCC/static/img/activities/16.gif b/AppGCC/static/img/activities/16.gif new file mode 100644 index 0000000000000000000000000000000000000000..036f2566294de1c483119aede213663c6606b50a Binary files /dev/null and b/AppGCC/static/img/activities/16.gif differ diff --git a/AppGCC/static/img/activities/17.png b/AppGCC/static/img/activities/17.png new file mode 100644 index 0000000000000000000000000000000000000000..7c6a75f3377334464acd60b11b623e39e96b2acd Binary files /dev/null and b/AppGCC/static/img/activities/17.png differ diff --git a/AppGCC/static/img/activities/18.gif b/AppGCC/static/img/activities/18.gif new file mode 100644 index 0000000000000000000000000000000000000000..516feeb0752ddcd3f94f5a9c82a7229411293c05 Binary files /dev/null and b/AppGCC/static/img/activities/18.gif differ diff --git a/AppGCC/static/img/activities/19.gif b/AppGCC/static/img/activities/19.gif new file mode 100644 index 0000000000000000000000000000000000000000..ed38e39f5632c5a660e43114639f26bc0c05eb6f Binary files /dev/null and b/AppGCC/static/img/activities/19.gif differ diff --git a/AppGCC/static/img/activities/2.jpg b/AppGCC/static/img/activities/2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1f40c89b7e2bccaea29dbe2dca59b3bef79c5350 Binary files /dev/null and b/AppGCC/static/img/activities/2.jpg differ diff --git a/AppGCC/static/img/activities/24.gif b/AppGCC/static/img/activities/24.gif new file mode 100644 index 0000000000000000000000000000000000000000..036f2566294de1c483119aede213663c6606b50a Binary files /dev/null and b/AppGCC/static/img/activities/24.gif differ diff --git a/AppGCC/static/img/activities/25.gif b/AppGCC/static/img/activities/25.gif new file mode 100644 index 0000000000000000000000000000000000000000..16950b1fd72025618b322798afd15f9fbd81cdca Binary files /dev/null and b/AppGCC/static/img/activities/25.gif differ diff --git a/AppGCC/static/img/activities/27.gif b/AppGCC/static/img/activities/27.gif new file mode 100644 index 0000000000000000000000000000000000000000..eff7a3e4032d9ea670c2982468aab1a801084378 Binary files /dev/null and b/AppGCC/static/img/activities/27.gif differ diff --git a/AppGCC/static/img/activities/31.gif b/AppGCC/static/img/activities/31.gif new file mode 100644 index 0000000000000000000000000000000000000000..b16f2bb3879c0675581a83960c26998deda09daa Binary files /dev/null and b/AppGCC/static/img/activities/31.gif differ diff --git a/AppGCC/static/img/activities/32.gif b/AppGCC/static/img/activities/32.gif new file mode 100644 index 0000000000000000000000000000000000000000..036f2566294de1c483119aede213663c6606b50a Binary files /dev/null and b/AppGCC/static/img/activities/32.gif differ diff --git a/AppGCC/static/img/activities/33.gif b/AppGCC/static/img/activities/33.gif new file mode 100644 index 0000000000000000000000000000000000000000..516feeb0752ddcd3f94f5a9c82a7229411293c05 Binary files /dev/null and b/AppGCC/static/img/activities/33.gif differ diff --git a/AppGCC/static/img/activities/34.jpg b/AppGCC/static/img/activities/34.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9eefd53d4a6588b5e51f3772facbf55af16c741e Binary files /dev/null and b/AppGCC/static/img/activities/34.jpg differ diff --git a/AppGCC/static/img/activities/35.gif b/AppGCC/static/img/activities/35.gif new file mode 100644 index 0000000000000000000000000000000000000000..87825b1f1e05455758e70b91d1bf5ca645b52bf1 Binary files /dev/null and b/AppGCC/static/img/activities/35.gif differ diff --git a/AppGCC/static/img/activities/40.gif b/AppGCC/static/img/activities/40.gif new file mode 100644 index 0000000000000000000000000000000000000000..3632187897d573badad7bff92f28a8a4ff1ece24 Binary files /dev/null and b/AppGCC/static/img/activities/40.gif differ diff --git a/AppGCC/static/img/activities/5.png b/AppGCC/static/img/activities/5.png new file mode 100644 index 0000000000000000000000000000000000000000..0a4f8de873cb81515bb18c429c5855bf4490ed4a Binary files /dev/null and b/AppGCC/static/img/activities/5.png differ diff --git a/AppGCC/static/img/activities/9.webp b/AppGCC/static/img/activities/9.webp new file mode 100644 index 0000000000000000000000000000000000000000..002c6231b727a1e1a912a5b2979d05ae41a3eb77 Binary files /dev/null and b/AppGCC/static/img/activities/9.webp differ diff --git a/AppGCC/users.csv b/AppGCC/users.csv new file mode 100644 index 0000000000000000000000000000000000000000..aac7e565eac688065f17e55357ed242750c07804 --- /dev/null +++ b/AppGCC/users.csv @@ -0,0 +1,23 @@ +21,Anto +22,Elvan +23,Thibaud +24,toutdanslebaltrou +25,anto +26,elvan +27,Pierre +28,Etienne +29,Mathilda +30,Bernard +31,Martine +32,dsjhfgsdjhgfjgdsjh +33,564564565465654674567456 +34,antovi +35,nuggy +36,benjos +37,test +38,caca +39,Benjamin +40,111 +41,eee +42,ooo +43,ggtgtgt