Ajout du module de gestion des utilisateurs et correction du formulaire

This commit is contained in:
2026-07-22 17:54:47 +02:00
parent c8d18a6cef
commit b974611196
2 changed files with 318 additions and 10 deletions
+86 -4
View File
@@ -1,12 +1,12 @@
from flask import Blueprint, render_template, request, redirect, url_for, session, flash from flask import Blueprint, render_template, request, redirect, url_for, session, flash
from werkzeug.security import check_password_hash from werkzeug.security import check_password_hash, generate_password_hash
from sqlalchemy import text from sqlalchemy import text
from app import db from app import db
from datetime import datetime from datetime import datetime
main = Blueprint('main', __name__) main = Blueprint('main', __name__)
/* routes */
@main.route('/', methods=['GET', 'POST']) @main.route('/', methods=['GET', 'POST'])
def index(): def index():
if 'user_id' in session: if 'user_id' in session:
@@ -50,8 +50,90 @@ def logout():
session.clear() session.clear()
return redirect(url_for('main.index')) return redirect(url_for('main.index'))
@main.route('/gestion-utilisateurs') @main.route('/gestion-utilisateurs', methods=['GET', 'POST'])
def gestion_utilisateurs(): def gestion_utilisateurs():
if 'user_id' not in session: if 'user_id' not in session:
return redirect(url_for('main.index')) return redirect(url_for('main.index'))
return render_template('gestion_utilisateurs.html')
if request.method == 'POST':
action = request.form.get('action')
user_id = request.form.get('id')
user_actif = request.form.get('actif', '1')
user_prenom = request.form.get('prenom')
user_nom = request.form.get('nom')
user_login = request.form.get('login')
user_mail = request.form.get('mail')
user_pass = request.form.get('pass')
if action == 'creer':
if user_pass:
hashed_pass = generate_password_hash(user_pass)
query = text("""
INSERT INTO login (login, nom, prenom, mail, pass, actif)
VALUES (:login, :nom, :prenom, :mail, :pass, :actif)
""")
db.session.execute(query, {
"login": user_login,
"nom": user_nom,
"prenom": user_prenom,
"mail": user_mail,
"pass": hashed_pass,
"actif": user_actif
})
db.session.commit()
flash("Utilisateur créé avec succès.", "success")
else:
flash("Le mot de passe est obligatoire pour créer un utilisateur.", "danger")
elif action == 'modifier' and user_id:
if user_pass:
hashed_pass = generate_password_hash(user_pass)
query = text("""
UPDATE login
SET login = :login, nom = :nom, prenom = :prenom, mail = :mail, pass = :pass, actif = :actif
WHERE id = :id
""")
db.session.execute(query, {
"id": user_id,
"login": user_login,
"nom": user_nom,
"prenom": user_prenom,
"mail": user_mail,
"pass": hashed_pass,
"actif": user_actif
})
else:
query = text("""
UPDATE login
SET login = :login, nom = :nom, prenom = :prenom, mail = :mail, actif = :actif
WHERE id = :id
""")
db.session.execute(query, {
"id": user_id,
"login": user_login,
"nom": user_nom,
"prenom": user_prenom,
"mail": user_mail,
"actif": user_actif
})
db.session.commit()
flash("Utilisateur modifié avec succès.", "success")
return redirect(url_for('main.gestion_utilisateurs'))
# Lecture exacte de la table login de votre base de données
users_query = text("SELECT id, login, nom, prenom, mail, actif FROM login ORDER BY id ASC")
result = db.session.execute(users_query)
users = []
for row in result:
users.append({
'id': row.id,
'login': row.login if row.login else '',
'nom': row.nom if row.nom else '',
'prenom': row.prenom if row.prenom else '',
'mail': row.mail if row.mail else '',
'actif': row.actif if row.actif is not None else 1
})
return render_template('gestion_utilisateurs.html', users=users)
+232 -6
View File
@@ -4,7 +4,7 @@ content %}
<div class="flex flex-col items-center justify-center py-6"> <div class="flex flex-col items-center justify-center py-6">
<!-- Box centrée principale --> <!-- Box centrée principale -->
<div <div
class="bg-gray-900 border border-gray-800 p-8 rounded-2xl shadow-2xl w-full max-w-4xl" class="bg-gray-900 border border-gray-800 p-8 rounded-2xl shadow-2xl w-full max-w-6xl"
> >
<!-- En-tête de section --> <!-- En-tête de section -->
<div <div
@@ -26,11 +26,186 @@ content %}
</a> </a>
</div> </div>
<!-- Contenu de la page --> <!-- Grille principale : Gauche (Liste) / Droite (Formulaire) -->
<div class="text-gray-300 py-8 text-center"> <div class="grid grid-cols-1 md:grid-cols-12 gap-8 py-4">
<p class="text-gray-400 italic"> <!-- COLONNE GAUCHE : Liste des utilisateurs réels de la BDD -->
Module de gestion des utilisateurs en cours de chargement... <div
</p> class="md:col-span-4 bg-gray-950 border border-gray-800 rounded-xl p-4 flex flex-col h-[520px]"
>
<h3
class="text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3 px-2"
>
Utilisateurs enregistrés
</h3>
<!-- Liste scrollable -->
<div class="overflow-y-auto flex-1 space-y-1 pr-1">
{% for u in users %}
<div
onclick="selectionnerUtilisateur('{{ u.id }}', '{{ u.actif }}', '{{ u.prenom }}', '{{ u.nom }}', '{{ u.login }}', '{{ u.mail }}')"
class="user-item cursor-pointer px-3 py-2.5 rounded-lg {% if loop.first %}bg-blue-600 text-white{% else %}hover:bg-gray-800 text-gray-300{% endif %} font-medium text-sm transition flex justify-between items-center"
data-id="{{ u.id }}"
>
<span>{{ u.prenom }} {{ u.nom }}</span>
<span
class="text-xs {% if loop.first %}bg-blue-800{% else %}bg-gray-800 text-gray-400{% endif %} px-2 py-0.5 rounded"
>ID: {{ u.id }}</span
>
</div>
{% endfor %}
</div>
</div>
<!-- COLONNE DROITE : Formulaire des détails -->
<div
class="md:col-span-8 bg-gray-950 border border-gray-800 rounded-xl p-6 flex flex-col justify-between"
>
<form
id="user-form"
method="POST"
action=""
class="space-y-4 flex-1 flex flex-col justify-between"
>
<div class="space-y-4">
<h3
class="text-sm font-semibold text-gray-300 uppercase tracking-wider mb-2"
>
Détails du compte
</h3>
<div class="grid grid-cols-2 gap-4">
<!-- ID (Lecture seule) -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>ID (Lecture seule)</label
>
<input
type="text"
id="field-id"
name="id"
readonly
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-gray-400 text-sm cursor-not-allowed"
/>
</div>
<!-- Actif / Statut -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>Actif (1 = Oui, 0 = Non)</label
>
<input
type="text"
id="field-actif"
name="actif"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<!-- Prénom -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>Prénom</label
>
<input
type="text"
id="field-prenom"
name="prenom"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<!-- Nom -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>Nom</label
>
<input
type="text"
id="field-nom"
name="nom"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<!-- Login -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>Login</label
>
<input
type="text"
id="field-login"
name="login"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<!-- Mail -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>E-mail</label
>
<input
type="email"
id="field-mail"
name="mail"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
</div>
<div>
<!-- Mot de passe -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>Nouveau mot de passe (laisser vide pour ne pas
changer)</label
>
<input
type="password"
id="field-pass"
name="pass"
placeholder="••••••••"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
</div>
</div>
<!-- Bas : Trois boutons (Créer, Modifier, Annuler) -->
<div
class="flex items-center justify-end space-x-3 pt-6 border-t border-gray-800 mt-6"
>
<button
type="button"
onclick="annulerAction()"
class="px-4 py-2 bg-gray-800 hover:bg-gray-700 text-gray-300 text-sm font-medium rounded-lg transition duration-200"
>
Annuler
</button>
<button
type="submit"
name="action"
value="creer"
class="px-4 py-2 bg-emerald-600 hover:bg-emerald-500 text-white text-sm font-medium rounded-lg transition duration-200"
>
Créer
</button>
<button
type="submit"
name="action"
value="modifier"
class="px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white text-sm font-medium rounded-lg transition duration-200"
>
Modifier
</button>
</div>
</form>
</div>
</div> </div>
<!-- Pied de page interne --> <!-- Pied de page interne -->
@@ -42,4 +217,55 @@ content %}
</div> </div>
</div> </div>
</div> </div>
<!-- Script de gestion de la sélection et du premier utilisateur par défaut -->
<!-- Script de gestion de la sélection -->
<script>
function selectionnerUtilisateur(id, actif, prenom, nom, login, mail) {
document.getElementById("field-id").value = id;
document.getElementById("field-actif").value = actif;
document.getElementById("field-prenom").value = prenom;
document.getElementById("field-nom").value = nom;
document.getElementById("field-login").value = login;
document.getElementById("field-mail").value = mail;
document.getElementById("field-pass").value = "";
document.querySelectorAll(".user-item").forEach((el) => {
el.classList.remove("bg-blue-600", "text-white");
el.classList.add("hover:bg-gray-800", "text-gray-300");
const badge = el.querySelector("span:last-child");
if (badge) {
badge.classList.remove("bg-blue-800");
badge.classList.add("bg-gray-800", "text-gray-400");
}
});
const selectedEl = document.querySelector(`[data-id="${id}"]`);
if (selectedEl) {
selectedEl.classList.remove("hover:bg-gray-800", "text-gray-300");
selectedEl.classList.add("bg-blue-600", "text-white");
const badge = selectedEl.querySelector("span:last-child");
if (badge) {
badge.classList.remove("bg-gray-800", "text-gray-400");
badge.classList.add("bg-blue-800");
}
}
}
function annulerAction() {
// Sélectionne le tout premier élément de la liste s'il existe
const premierUser = document.querySelector(".user-item");
if (premierUser) {
premierUser.click();
}
}
// Sélectionner automatiquement le premier utilisateur au chargement de la page
window.addEventListener("DOMContentLoaded", () => {
const premierUser = document.querySelector(".user-item");
if (premierUser) {
premierUser.click();
}
});
</script>
{% endblock %} {% endblock %}