Skip to content
Snippets Groups Projects
Commit 14842999 authored by DUVAL Elvan's avatar DUVAL Elvan
Browse files

Logo et equipe

parent a53fa2cb
No related branches found
No related tags found
No related merge requests found
Showing
with 288 additions and 100 deletions
No preview for this file type
No preview for this file type
No preview for this file type
......@@ -6,25 +6,38 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<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">
</head>
<body class="bg-[#dfdbec] flex flex-col items-center justify-between min-h-screen p-6">
<!-- Main Container -->
<div class="bg-white p-8 rounded-2xl shadow-2xl w-full max-w-3xl">
<!-- User Profile Section -->
<div class="flex items-center justify-between mb-6">
<!-- Partie gauche : Profil utilisateur -->
<div class="flex items-center">
<img src="{% static 'img/default-avatar.png' %}" alt="Avatar" class="h-16 w-16 rounded-full shadow-lg border-2 border-[#102564] cursor-pointer" onclick="toggleProfilePopup()">
<!-- Avatar dynamique basé sur le nom d'utilisateur -->
<img src="https://ui-avatars.com/api/?name={{ user.username }}&background=102564&color=fff&size=128"
alt="Avatar" class="h-16 w-16 rounded-full shadow-lg border-2 border-[#102564] cursor-pointer" onclick="toggleProfilePopup()">
<div class="ml-4">
<p class="text-2xl font-semibold text-[#102564]">{{ user.username }}</p>
<p class="text-sm text-gray-500">Bienvenue, {{ user.username }}</p>
</div>
</div>
<!-- Logo centré -->
<div class="flex justify-center flex-1">
<img src="{% static 'img/chadfit1024.png' %}" alt="Logo" class="h-20 w-auto shadow-lg rounded-lg">
</div>
<!-- Bouton déconnexion -->
<div class="flex space-x-4">
<a href="{% url 'logout' %}" class="bg-[#102564] text-white py-2 px-4 rounded-lg shadow-md hover:bg-[#000000] transition duration-300">Se déconnecter</a>
<a href="{% url 'logout' %}" class="bg-[#102564] text-white py-2 px-4 rounded-lg shadow-md hover:bg-[#000000] transition duration-300"><i class="fas fa-sign-out-alt"></i><span> Se déconnecter</span></a>
</div>
</div>
<!-- Title -->
<h2 class="text-3xl font-bold text-[#102564] text-center mb-6">Mes Challenges du Jour</h2>
......@@ -39,7 +52,7 @@
<span class="text-sm text-gray-500">Lieu: {{ challenge.lieu }}</span>
<span class="text-sm text-gray-500">Points: {{ challenge.points }}</span>
</div>
<button 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>
<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 %}
</ul>
......@@ -47,9 +60,20 @@
<!-- Navigation Bar -->
<div class="fixed bottom-0 w-full bg-[#102564] text-white flex justify-around py-3 shadow-md">
<a href="{% url 'challenges' %}" class="text-lg font-semibold hover:text-gray-300">Accueil</a>
<a href="{% url 'ranking' %}" class="text-lg font-semibold hover:text-gray-300">Classement</a>
<a href="{% url 'challenges' %}" class="text-lg font-semibold hover:text-gray-300 flex items-center space-x-2">
<!-- Icône Maison (Accueil) -->
<i class="fas fa-home text-white text-2xl"></i>
<span>Accueil</span>
</a>
<a href="{% url 'ranking' %}" class="text-lg font-semibold hover:text-gray-300 flex items-center space-x-2">
<!-- Icône Coupe (Classement) -->
<i class="fas fa-trophy text-[#cd7f32] text-2xl"></i>
<span>Classement</span>
</a>
</div>
<!-- Profile Popup -->
<div id="profilePopup" class="hidden fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center">
......@@ -80,6 +104,37 @@
document.getElementById("profilePopup").classList.toggle("hidden");
}
function getCookie(name) {
let value = "; " + document.cookie;
let parts = value.split("; " + name + "=");
if (parts.length === 2) return parts.pop().split(";").shift();
}
function addValidatedChallenge(challengeId) {
let existing = getCookie("validatedChallenges");
let validatedList = existing ? existing.split(",") : [];
if (!validatedList.includes(challengeId)) {
validatedList.push(challengeId);
document.cookie = "validatedChallenges=" + validatedList.join(",") + "; path=/; max-age=" + (7*24*60*60);
}
}
function checkValidatedButtons() {
let existing = getCookie("validatedChallenges");
if (existing) {
let validatedList = existing.split(",");
validatedList.forEach(id => {
let button = document.getElementById(`validate-btn-${id}`);
if (button) {
button.innerText = "Déjà validé ✅";
button.disabled = true;
button.classList.remove("hover:bg-[#000000]");
button.classList.add("bg-green-500", "cursor-not-allowed");
}
});
}
}
function completeChallenge(challengeId) {
fetch("/complete_challenge/", {
method: "POST",
......@@ -92,6 +147,14 @@
.then(response => response.json())
.then(data => {
if (data.status == "success") {
const button = document.getElementById(`validate-btn-${challengeId}`);
if (button) {
button.innerText = "Déjà validé ✅";
button.disabled = true;
button.classList.remove("hover:bg-[#000000]");
button.classList.add("bg-green-500", "cursor-not-allowed");
}
addValidatedChallenge(challengeId);
document.getElementById("confirmationText").innerText = data.message + " (" + data.points + " points)";
document.getElementById("confirmationMessage").classList.remove("hidden");
} else {
......@@ -102,7 +165,6 @@
function closeConfirmationMessage() {
document.getElementById("confirmationMessage").classList.add("hidden");
location.reload();
}
function saveProfileSettings() {
......@@ -125,6 +187,8 @@
}
});
}
window.onload = checkValidatedButtons;
</script>
</body>
</html>
\ No newline at end of file
</html>
......@@ -26,6 +26,9 @@
<label for="username" class="block text-sm font-medium text-[#000000]">Nom d'utilisateur:</label>
<input type="text" name="username" id="username" required
class="w-full p-3 mt-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-[#102564] focus:border-[#102564]">
<label for="team" class="block text-sm font-medium text-[#000000]">Nom d'équipe:</label>
<input type="text" name="team" id="team"
class="w-full p-3 mt-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-[#102564] focus:border-[#102564]">
</div>
<!-- Submit Button -->
......
......@@ -6,45 +6,95 @@
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
</head>
<body class="bg-[#dfdbec] flex items-center justify-center min-h-screen p-6">
<div class="bg-white p-8 rounded-2xl shadow-2xl w-full max-w-3xl">
<h2 class="text-3xl font-bold text-[#102564] text-center mb-6">Classement</h2>
<ul class="space-y-4">
{% for user in ranking %}
<li class="flex items-center justify-between p-4
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 w-full max-w-6xl">
<!-- Bloc Utilisateur -->
<div class="bg-white p-8 rounded-2xl shadow-2xl">
<h2 class="text-xl sm:text-2xl md:text-3xl font-bold text-[#102564] text-center mb-6">Classement Utilisateurs</h2>
<ul class="space-y-4">
{% for user in ranking %}
<li class="flex items-center justify-between p-4
{% if forloop.counter == 1 %}
bg-gradient-to-r from-yellow-500 to-yellow-400 text-white text-base sm:text-lg md:text-xl lg:text-2xl
{% elif forloop.counter == 2 %}
bg-gradient-to-r from-gray-400 to-gray-300 text-white text-base sm:text-lg md:text-xl lg:text-2xl
{% elif forloop.counter == 3 %}
bg-gradient-to-r from-[#cd7f32] to-[#b56d4e] text-white text-base sm:text-lg md:text-xl lg:text-2xl
{% else %}
bg-gray-100 text-[#102564] text-base sm:text-lg md:text-xl lg:text-2xl
{% endif %}
rounded-lg shadow-lg hover:shadow-xl transition duration-300">
<div class="flex items-center space-x-3">
{% if forloop.counter == 1 %}
bg-gradient-to-r from-yellow-500 to-yellow-400 text-white text-2xl
<i class="fas fa-medal text-yellow-300"></i>
{% elif forloop.counter == 2 %}
bg-gradient-to-r from-gray-400 to-gray-300 text-white text-xl
<i class="fas fa-medal text-gray-200"></i>
{% elif forloop.counter == 3 %}
bg-gradient-to-r from-[#cd7f32] to-[#b56d4e] text-white text-xl
{% else %}
bg-gray-100 text-[#102564] text-lg
<i class="fas fa-medal text-[#d49e6a]"></i>
{% endif %}
rounded-lg shadow-lg hover:shadow-xl transition duration-300">
<div class="flex items-center space-x-3">
{% if forloop.counter == 1 %}
<i class="fas fa-medal text-yellow-300"></i>
{% elif forloop.counter == 2 %}
<i class="fas fa-medal text-gray-200"></i>
{% elif forloop.counter == 3 %}
<i class="fas fa-medal text-[#d49e6a]"></i>
{% endif %}
<div class="flex flex-col">
<span class="font-medium">{{ user.username }}</span>
<span class="text-sm text-gray-500">Points: {{ user.score }}</span>
<div class="flex flex-col">
<span class="font-medium">{{ user.username }} ({{ user.user_team }})</span>
<span class="text-sm text-gray-500">Points: {{ user.score }}</span>
</div>
</div>
</div>
<span class="font-medium">{{ forloop.counter }}</span>
</li>
{% endfor %}
</ul>
<span class="font-medium">{{ forloop.counter }}</span>
</li>
{% endfor %}
</ul>
</div>
<!-- Bloc Équipe -->
<div class="bg-white p-8 rounded-2xl shadow-2xl">
<h2 class="text-xl sm:text-2xl md:text-3xl font-bold text-[#102564] text-center mb-6">Classement Équipes</h2>
<ul class="space-y-4">
{% for team in team_ranking %}
<li class="flex items-center justify-between p-4
{% if forloop.counter == 1 %}
bg-gradient-to-r from-green-500 to-green-400 text-white text-base sm:text-lg md:text-xl lg:text-2xl
{% elif forloop.counter == 2 %}
bg-gradient-to-r from-blue-400 to-blue-300 text-white text-base sm:text-lg md:text-xl lg:text-2xl
{% elif forloop.counter == 3 %}
bg-gradient-to-r from-purple-400 to-purple-300 text-white text-base sm:text-lg md:text-xl lg:text-2xl
{% else %}
bg-gray-100 text-[#102564] text-base sm:text-lg md:text-xl lg:text-2xl
{% endif %}
rounded-lg shadow-lg hover:shadow-xl transition duration-300">
<div class="flex items-center space-x-3">
{% if forloop.counter == 1 %}
<i class="fas fa-trophy text-yellow-300"></i>
{% elif forloop.counter == 2 %}
<i class="fas fa-trophy text-gray-300"></i>
{% elif forloop.counter == 3 %}
<i class="fas fa-trophy text-[#cd7f32]"></i>
{% endif %}
<div class="flex flex-col">
<span class="font-medium">{{ team.team }}</span>
<span class="text-sm text-gray-500">Points: {{ team.score }}</span>
</div>
</div>
<span class="font-medium">{{ forloop.counter }}</span>
</li>
{% endfor %}
</ul>
</div>
</div>
<!-- Navigation Bar -->
<div class="fixed bottom-0 w-full bg-[#102564] text-white flex justify-around py-3 shadow-md">
<a href="{% url 'challenges' %}" class="text-lg font-semibold hover:text-gray-300">Accueil</a>
<a href="{% url 'ranking' %}" class="text-lg font-semibold hover:text-gray-300">Classement</a>
<a href="{% url 'challenges' %}" class="text-lg font-semibold hover:text-gray-300 flex items-center space-x-2">
<!-- Icône Maison (Accueil) -->
<i class="fas fa-home text-white text-2xl"></i>
<span>Accueil</span>
</a>
<a href="{% url 'ranking' %}" class="text-lg font-semibold hover:text-gray-300 flex items-center space-x-2">
<!-- Icône Coupe (Classement) -->
<i class="fas fa-trophy text-[#cd7f32] text-2xl"></i>
<span>Classement</span>
</a>
</div>
</body>
</html>
\ No newline at end of file
</html>
......@@ -36,9 +36,10 @@ 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")
user = User.objects.filter(username=username).first()
if user is None:
user = User.objects.create_user(username=username, password=None)
user = User.objects.create_user(username=username, password=None, last_name=team)
user.save()
add_user_to_csv(username, user.id)
login(request, user)
......@@ -74,20 +75,43 @@ def ranking_view(request):
# 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
ranking.append({"username": users[int(user_id)], "score": score})
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:
team = entry["user_team"]
if team not in team_scores:
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({
"team": team,
"score": score
})
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})
return render(request, "ranking.html", {"ranking": ranking, "team_ranking": team_ranking})
def read_users():
"""Lire les utilisateurs depuis django"""
......@@ -98,6 +122,15 @@ def read_users():
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
#####################
# Page de Challenge #
#####################
......
No preview for this file type
2,difficile
17,difficile
user_id,score
2,49
17,10
18,26
19,36
12,Bonjour
13,qqqqq
14,dffsd
15,uuuuuuuu
17,oiewuytourytyretyutyttyrtyruryturyturtyruty
18,yyyyy
19,ttrertertet
1,Étirements des bras et épaules (2 min),Facile,Au bureau (poste),5,arrows-move
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),6,arrow-up-circle
3,S'asseoir et se lever de sa chaise (10 fois),Facile,Au bureau (poste),5,arrow-up-circle
4,Tenir 30 sec en équilibre sur un pied,Facile,Au bureau (poste),5,accessibility
5,Rotations poignets et épaules (1 min),Facile,Au bureau (poste),5,refresh
6,Prendre les escaliers toute la journée,Facile,Au bureau (espaces communs),8,stairs
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,footprints
8,Marcher 5 min après chaque réunion,Facile,Au bureau (espaces communs),8,clock
9,Flexions des genoux (10 fois),Facile,Au bureau (espaces communs),6,arrow-down-circle
10,Respiration profonde (5 fois),Facile,Au bureau (espaces communs),5,wind
11,Marche rapide (10 min) pause déjeuner,Facile,Extérieur,10,walk
12,Descendre un arrêt plus tôt,Facile,Extérieur,10,bus
13,Aller voir un collègue au lieu d’un e-mail,Facile,Extérieur,5,mail-opened
14,Balade autour du bureau,Facile,Extérieur,9,trees
15,20 montées de marches en extérieur,Facile,Extérieur,10,stairs
16,10 squats sans quitter son bureau,Moyen,Au bureau (poste),10,run
17,Gainage sur chaise (30 sec),Moyen,Au bureau (poste),10,grip-horizontal
18,20 extensions de mollets,Moyen,Au bureau (poste),10,walk
19,30 contractions abdos assis,Moyen,Au bureau (poste),10,user
20,Alterner assis/debout toutes les 30 min (2h),Moyen,Au bureau (poste),12,clock
21,Escaliers 3 jours d’affilée,Moyen,Au bureau (espaces communs),15,stairs
22,Se lever et marcher 5 min toutes les heures,Moyen,Au bureau (espaces communs),12,clock
23,10 montées de marches,Moyen,Au bureau (espaces communs),12,stairs
24,15 squats en salle de repos,Moyen,Au bureau (espaces communs),12,dumbbell
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,arrow-down-circle
10,Respiration profonde (5 fois),Facile,Au bureau (espaces communs),10,wind
11,Marche rapide (10 min) pause déjeuner,Facile,Extérieur,15,walk
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,mail-opened
14,Balade autour du bureau,Facile,Extérieur,15,trees
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,run
17,Gainage sur chaise (30 sec),Moyen,Au bureau (poste),5,grip-horizontal
18,20 extensions de mollets,Moyen,Au bureau (poste),5,walk
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,refresh
26,Marche rapide (15 min),Moyen,Extérieur,12,walk
27,10 flexions jambes en attendant métro,Moyen,Extérieur,10,bus
26,Marche rapide (15 min),Moyen,Extérieur,15,walk
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,bike
29,7500 pas dans la journée,Moyen,Extérieur,15,footprints
30,Balade de 20 min en fin de journée,Moyen,Extérieur,14,trees
31,Gainage contre mur (1 min),Difficile,Au bureau (poste),15,grip-horizontal
32,20 squats en plusieurs fois,Difficile,Au bureau (poste),15,run
33,50 extensions de mollets,Difficile,Au bureau (poste),15,walk
34,Planche sur chaise (2 min),Difficile,Au bureau (poste),18,grip-horizontal
35,50 contractions abdos assis,Difficile,Au bureau (poste),15,user
36,Escaliers uniquement (5 jours consécutifs),Difficile,Au bureau (espaces communs),20,stairs
37,Marche 10 min après déjeuner (3 jours),Difficile,Au bureau (espaces communs),20,walk
38,Défi collectif avec 3 collègues,Difficile,Au bureau (espaces communs),15,users
39,Se lever et marcher toutes les 30 min,Difficile,Au bureau (espaces communs),18,clock
40,3 min de montées de genoux salle de repos,Difficile,Au bureau (espaces communs),18,run
41,10000 pas dans la journée,Difficile,Extérieur,20,footprints
42,Balade de 30 min après le travail,Difficile,Extérieur,20,trees
43,Aller au travail à vélo (3x/semaine),Difficile,Extérieur,25,bike
44,Marcher/courir 5 km en dehors du bureau,Difficile,Extérieur,25,footprints
45,Séance collective sportive extérieure,Difficile,Extérieur,22,users
30,Balade de 20 min en fin de journée,Moyen,Extérieur,15,trees
31,Gainage contre mur (1 min),Difficile,Au bureau (poste),5,grip-horizontal
32,20 squats en plusieurs fois,Difficile,Au bureau (poste),5,run
33,50 extensions de mollets,Difficile,Au bureau (poste),5,walk
34,Planche sur chaise (2 min),Difficile,Au bureau (poste),5,grip-horizontal
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,walk
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,run
41,10000 pas dans la journée,Difficile,Extérieur,15,footprints
42,Balade de 30 min après le travail,Difficile,Extérieur,15,trees
43,Aller au travail à vélo (3x/semaine),Difficile,Extérieur,15,bike
44,Marcher/courir 5 km en dehors du bureau,Difficile,Extérieur,15,footprints
45,Séance collective sportive extérieure,Difficile,Extérieur,15,users
......@@ -9,3 +9,17 @@
2025-03-12,17,18,21,30
2025-03-12,18,16,22,30
2025-03-12,19,28,18,22
2025-03-19,20,17,29,21
2025-03-19,1,30,18,23
2025-03-19,21,17,25,29
2025-03-19,22,17,26,25
2025-03-19,23,27,22,20
2025-03-19,24,28,18,24
2025-03-19,,20,29,21
2025-03-19,25,22,30,16
2025-03-19,26,16,29,25
2025-03-19,27,26,17,22
2025-03-19,28,18,21,26
2025-03-19,29,17,27,22
2025-03-19,30,19,24,30
2025-03-19,31,19,22,30
Elvan,moyen
2,difficile
17,difficile
22,difficile
No preview for this file type
No preview for this file type
No preview for this file type
username,score
Thibaud,100
Elvan,800
buval,100
user_id,score
2,49
17,10
18,26
19,36
20,75
21,60
1,50
22,135
23,96
24,22
25,12
26,5
27,20
28,15
29,15
30,30
31,30
21,Anto
22,Elvan
23,Thibaud
24,toutdanslebaltrou
25,anto
26,elvan
27,Pierre
28,Etienne
29,Mathilda
30,Bernard
31,Martine
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment