From ea70c15d112321a4b15c751ecd57d1cbec365eac Mon Sep 17 00:00:00 2001 From: Adrien Fryson <adrien.fryson@outlook.com> Date: Wed, 12 Mar 2025 21:18:10 +0100 Subject: [PATCH] parametres utilisateur --- sae/WEB-INF/src/controleur/Parametre.java | 58 ++++++++++++++++++ sae/WEB-INF/src/modele/AbonnementDao.java | 1 + .../src/modele/FilDeDiscussionDAO.java | 2 +- sae/WEB-INF/src/modele/MessageDao.java | 4 +- sae/WEB-INF/src/modele/UtilisateurDao.java | 3 +- sae/WEB-INF/vue/accueil.jsp | 3 +- sae/WEB-INF/vue/creerFil.jsp | 1 + sae/WEB-INF/vue/fil.jsp | 5 +- sae/WEB-INF/vue/listerFil.jsp | 1 + sae/WEB-INF/vue/login.jsp | 1 + sae/WEB-INF/vue/menuFil.jsp | 1 + sae/WEB-INF/vue/parametre.jsp | 60 +++++++++++++++++++ sae/WEB-INF/vue/register.jsp | 1 + script.sql | 6 +- 14 files changed, 136 insertions(+), 11 deletions(-) create mode 100644 sae/WEB-INF/src/controleur/Parametre.java create mode 100644 sae/WEB-INF/vue/parametre.jsp diff --git a/sae/WEB-INF/src/controleur/Parametre.java b/sae/WEB-INF/src/controleur/Parametre.java new file mode 100644 index 0000000..8da9bb5 --- /dev/null +++ b/sae/WEB-INF/src/controleur/Parametre.java @@ -0,0 +1,58 @@ +package controleur; + +import java.io.IOException; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import modele.AbonnementDao; +import modele.FilDeDiscussionDAO; +import modele.MessageDao; +import modele.Utilisateur; +import modele.UtilisateurDao; +import org.apache.commons.text.StringEscapeUtils; + +@WebServlet("/parametre") +public class Parametre extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + if (req.getSession(false) == null || req.getSession().getAttribute("email") == null) { + res.sendRedirect(req.getContextPath() + "/login"); + return; + } + req.getRequestDispatcher("/WEB-INF/vue/parametre.jsp").forward(req, res); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + if (req.getSession(false) == null || req.getSession().getAttribute("email") == null) { + res.sendRedirect(req.getContextPath() + "/login"); + return; + } + + String email = (String) req.getSession().getAttribute("email"); + String nom = StringEscapeUtils.escapeHtml4(req.getParameter("nom")); + String newEmail = StringEscapeUtils.escapeHtml4(req.getParameter("email")); + String motdepasse = StringEscapeUtils.escapeHtml4(req.getParameter("motdepasse")); + + UtilisateurDao udao = new UtilisateurDao(); + if (!email.equals(newEmail) && udao.emailExists(newEmail)) { + req.setAttribute("error", "Cet email est déjà utilisé."); + req.getRequestDispatcher("/WEB-INF/vue/parametre.jsp").forward(req, res); + return; + } + + Utilisateur utilisateur = udao.findUtilisateur(email); + utilisateur.setNom(nom); + utilisateur.setEmail(newEmail); + if (motdepasse != null && !motdepasse.isEmpty()) { + utilisateur.setMotDePasse(motdepasse); + } + + udao.update(utilisateur, email); + req.getSession().setAttribute("email", newEmail); + res.sendRedirect(req.getContextPath() + "/accueil"); + } +} diff --git a/sae/WEB-INF/src/modele/AbonnementDao.java b/sae/WEB-INF/src/modele/AbonnementDao.java index 151db56..51021fb 100644 --- a/sae/WEB-INF/src/modele/AbonnementDao.java +++ b/sae/WEB-INF/src/modele/AbonnementDao.java @@ -3,6 +3,7 @@ package modele; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.List; import java.util.ArrayList; diff --git a/sae/WEB-INF/src/modele/FilDeDiscussionDAO.java b/sae/WEB-INF/src/modele/FilDeDiscussionDAO.java index 15ca49d..4553a75 100644 --- a/sae/WEB-INF/src/modele/FilDeDiscussionDAO.java +++ b/sae/WEB-INF/src/modele/FilDeDiscussionDAO.java @@ -3,6 +3,7 @@ package modele; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @@ -89,5 +90,4 @@ public class FilDeDiscussionDAO { System.err.println(e.getMessage()); } } - } diff --git a/sae/WEB-INF/src/modele/MessageDao.java b/sae/WEB-INF/src/modele/MessageDao.java index b1604a6..b95fbb2 100644 --- a/sae/WEB-INF/src/modele/MessageDao.java +++ b/sae/WEB-INF/src/modele/MessageDao.java @@ -3,6 +3,7 @@ package modele; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.List; import java.util.ArrayList; @@ -139,7 +140,4 @@ public class MessageDao { return false; } } - - - } diff --git a/sae/WEB-INF/src/modele/UtilisateurDao.java b/sae/WEB-INF/src/modele/UtilisateurDao.java index cb0fce6..a138867 100644 --- a/sae/WEB-INF/src/modele/UtilisateurDao.java +++ b/sae/WEB-INF/src/modele/UtilisateurDao.java @@ -48,12 +48,13 @@ public class UtilisateurDao { } } - public void update(Utilisateur utilisateur) { + public void update(Utilisateur utilisateur, String oldEmail) { try(Connection con = DS.instance.getConnection()) { PreparedStatement ps = con.prepareStatement("UPDATE Utilisateur SET nom = ?, email = ?, motdepasse = ? WHERE email = ?"); ps.setString(1, utilisateur.getNom()); ps.setString(2, utilisateur.getEmail()); ps.setString(3, utilisateur.getMotDePasse()); + ps.setString(4, oldEmail); ps.executeUpdate(); } catch (Exception e) { System.out.println(e.getMessage()); diff --git a/sae/WEB-INF/vue/accueil.jsp b/sae/WEB-INF/vue/accueil.jsp index fe9569f..d4a5831 100644 --- a/sae/WEB-INF/vue/accueil.jsp +++ b/sae/WEB-INF/vue/accueil.jsp @@ -28,6 +28,7 @@ <a href="<%= request.getContextPath() %>/accueil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Accueil</a> <a href="<%= request.getContextPath() %>/listerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Autres Fils de Discussion</a> <a href="<%= request.getContextPath() %>/creerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Créer un Fil</a> + <a href="<%= request.getContextPath() %>/parametre" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Paramètres</a> <a href="<%= request.getContextPath() %>/logout" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-red-700">Se déconnecter</a> </nav> </aside> @@ -63,7 +64,7 @@ for (FilDeDiscussion f : fddao.findAll()) { if (abonnementsIds.contains(f.getId())) { %> - <div class="mb-4 p-4 bg-gray-700 rounded-lg shadow-md"> + <div class="mb-4 p-4 bg-gray-700 rounded-lg shadow-md hover:bg-gray-600"> <a href="<%= request.getContextPath() %>/fil?id=<%= f.getId() %>" class="block"> <img src="<%= request.getContextPath() %>/images/<%= f.getLogo() %>" alt="Logo" class="w-16 h-16 mx-auto"> <h4 class="font-bold text-lg"><%= f.getNom() %></h4> diff --git a/sae/WEB-INF/vue/creerFil.jsp b/sae/WEB-INF/vue/creerFil.jsp index 9ebc55c..a74d25b 100644 --- a/sae/WEB-INF/vue/creerFil.jsp +++ b/sae/WEB-INF/vue/creerFil.jsp @@ -19,6 +19,7 @@ <a href="<%= request.getContextPath() %>/accueil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Accueil</a> <a href="<%= request.getContextPath() %>/listerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Autres Fils de Discussion</a> <a href="<%= request.getContextPath() %>/creerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Créer un Fil</a> + <a href="<%= request.getContextPath() %>/parametre" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Paramètres</a> <a href="<%= request.getContextPath() %>/logout" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-red-700">Se déconnecter</a> </nav> </aside> diff --git a/sae/WEB-INF/vue/fil.jsp b/sae/WEB-INF/vue/fil.jsp index 3ef1a03..ce25440 100644 --- a/sae/WEB-INF/vue/fil.jsp +++ b/sae/WEB-INF/vue/fil.jsp @@ -40,6 +40,7 @@ <a href="<%= request.getContextPath() %>/accueil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Accueil</a> <a href="<%= request.getContextPath() %>/listerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Autres Fils de Discussion</a> <a href="<%= request.getContextPath() %>/creerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Créer un Fil</a> + <a href="<%= request.getContextPath() %>/parametre" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Paramètres</a> <a href="<%= request.getContextPath() %>/logout" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-red-700">Se déconnecter</a> </nav> </aside> @@ -97,9 +98,9 @@ </form> </div> <% if (session.getAttribute("email").equals(m.getAuteurEmail())) { %> - <form action="<%= request.getContextPath() %>/deleteMessage" method="post" class="mt-2"> + <form action="<%= request.getContextPath() %>/deleteMessage" method="post" class="mt-2" onsubmit="return confirm('Êtes-vous sûr de vouloir supprimer ce message ?');"> <input type="hidden" name="messageId" value="<%= m.getId() %>"> - <button type="submit" class="text-red-500 hover:text-red-700">delete</button> + <button type="submit" class="text-red-500 hover:text-red-700">Supprimer</button> </form> <% } %> </div> diff --git a/sae/WEB-INF/vue/listerFil.jsp b/sae/WEB-INF/vue/listerFil.jsp index 40ce904..51f0e06 100644 --- a/sae/WEB-INF/vue/listerFil.jsp +++ b/sae/WEB-INF/vue/listerFil.jsp @@ -26,6 +26,7 @@ <a href="<%= request.getContextPath() %>/accueil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Accueil</a> <a href="<%= request.getContextPath() %>/listerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Autres Fils de Discussion</a> <a href="<%= request.getContextPath() %>/creerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Créer un Fil</a> + <a href="<%= request.getContextPath() %>/parametre" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Paramètres</a> <a href="<%= request.getContextPath() %>/logout" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-red-700">Se déconnecter</a> </nav> </aside> diff --git a/sae/WEB-INF/vue/login.jsp b/sae/WEB-INF/vue/login.jsp index a81985e..160e7b1 100644 --- a/sae/WEB-INF/vue/login.jsp +++ b/sae/WEB-INF/vue/login.jsp @@ -19,6 +19,7 @@ <a href="<%= request.getContextPath() %>/accueil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Accueil</a> <a href="<%= request.getContextPath() %>/listerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Autres Fils de Discussion</a> <a href="<%= request.getContextPath() %>/creerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Créer un Fil</a> + <a href="<%= request.getContextPath() %>/parametre" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Paramètres</a> <a href="<%= request.getContextPath() %>/logout" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-red-700">Se déconnecter</a> </nav> </aside> diff --git a/sae/WEB-INF/vue/menuFil.jsp b/sae/WEB-INF/vue/menuFil.jsp index 4cde7c2..fbb3bff 100644 --- a/sae/WEB-INF/vue/menuFil.jsp +++ b/sae/WEB-INF/vue/menuFil.jsp @@ -27,6 +27,7 @@ <a href="<%= request.getContextPath() %>/accueil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Accueil</a> <a href="<%= request.getContextPath() %>/listerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Autres Fils de Discussion</a> <a href="<%= request.getContextPath() %>/creerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Créer un Fil</a> + <a href="<%= request.getContextPath() %>/parametre" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Paramètres</a> <a href="<%= request.getContextPath() %>/logout" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-red-700">Se déconnecter</a> </nav> </aside> diff --git a/sae/WEB-INF/vue/parametre.jsp b/sae/WEB-INF/vue/parametre.jsp new file mode 100644 index 0000000..e434325 --- /dev/null +++ b/sae/WEB-INF/vue/parametre.jsp @@ -0,0 +1,60 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ page import="modele.Utilisateur" %> +<%@ page import="modele.UtilisateurDao" %> + +<% + String email = (String) session.getAttribute("email"); + UtilisateurDao udao = new UtilisateurDao(); + Utilisateur utilisateur = udao.findUtilisateur(email); +%> + +<!DOCTYPE html> +<html lang="fr"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>CampusTalk - Paramètres du Compte</title> + <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> + <link rel="shortcut icon" href="<%= request.getContextPath() %>/images/logo.png"> +</head> +<body class="bg-gray-900 text-white flex"> + <aside class="w-64 bg-gray-800 text-white h-screen"> + <div class="p-4 text-center"> + <img src="<%= request.getContextPath() %>/images/logo.png" alt="CampusTalk Logo" class="w-16 h-16 mx-auto"> + <h1 class="text-2xl font-bold mt-4">CampusTalk</h1> + </div> + <nav class="mt-4"> + <a href="<%= request.getContextPath() %>/accueil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Accueil</a> + <a href="<%= request.getContextPath() %>/listerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Autres Fils de Discussion</a> + <a href="<%= request.getContextPath() %>/creerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Créer un Fil</a> + <a href="<%= request.getContextPath() %>/parametre" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Paramètres</a> + <a href="<%= request.getContextPath() %>/logout" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-red-700">Se déconnecter</a> + </nav> + </aside> + <div class="flex-1 p-6"> + <div class="max-w-md mx-auto mt-12 p-6 bg-gray-800 rounded-lg shadow-md"> + <h2 class="text-2xl font-bold mb-4 text-center">Paramètres du Compte</h2> + <% if (request.getAttribute("error") != null) { %> + <div class="bg-red-100 text-red-700 p-4 rounded-lg mb-4"> + <%= request.getAttribute("error") %> + </div> + <% request.removeAttribute("error"); } %> + <form action="<%= request.getContextPath() %>/parametre" method="post"> + <div class="mb-4"> + <label for="nom" class="block text-gray-300 font-semibold">Nom</label> + <input type="text" class="w-full p-3 border border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400 bg-gray-700 text-white" name="nom" id="nom" value="<%= utilisateur.getNom() %>" required> + </div> + <div class="mb-4"> + <label for="email" class="block text-gray-300 font-semibold">Adresse e-mail</label> + <input type="email" class="w-full p-3 border border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400 bg-gray-700 text-white" name="email" id="email" value="<%= utilisateur.getEmail() %>" required> + </div> + <div class="mb-4"> + <label for="motdepasse" class="block text-gray-300 font-semibold">Nouveau mot de passe</label> + <input type="password" class="w-full p-3 border border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400 bg-gray-700 text-white" name="motdepasse" id="motdepasse" placeholder="Laissez vide pour ne pas changer"> + </div> + <button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded-lg shadow-md hover:bg-blue-600 transition-colors w-full">Sauvegarder</button> + </form> + </div> + </div> +</body> +</html> diff --git a/sae/WEB-INF/vue/register.jsp b/sae/WEB-INF/vue/register.jsp index 97b79ba..5bbda6d 100644 --- a/sae/WEB-INF/vue/register.jsp +++ b/sae/WEB-INF/vue/register.jsp @@ -19,6 +19,7 @@ <a href="<%= request.getContextPath() %>/accueil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Accueil</a> <a href="<%= request.getContextPath() %>/listerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Autres Fils de Discussion</a> <a href="<%= request.getContextPath() %>/creerFil" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Créer un Fil</a> + <a href="<%= request.getContextPath() %>/parametre" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-700">Paramètres</a> <a href="<%= request.getContextPath() %>/logout" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-red-700">Se déconnecter</a> </nav> </aside> diff --git a/script.sql b/script.sql index 5d0f9ac..84686da 100644 --- a/script.sql +++ b/script.sql @@ -20,7 +20,7 @@ CREATE TABLE FilDeDiscussion ( logo VARCHAR(255) DEFAULT 'default.png', CONSTRAINT pk_fil PRIMARY KEY (id), CONSTRAINT fk_createur FOREIGN KEY (createurEmail) REFERENCES Utilisateur(email) - ON DELETE SET NULL + ON DELETE SET NULL ON UPDATE CASCADE ); CREATE TABLE Message ( @@ -35,7 +35,7 @@ CREATE TABLE Message ( CONSTRAINT fk_fil FOREIGN KEY (filId) REFERENCES FilDeDiscussion(id) ON DELETE CASCADE, CONSTRAINT fk_auteur FOREIGN KEY (auteurEmail) REFERENCES Utilisateur(email) - ON DELETE SET NULL + ON DELETE SET NULL ON UPDATE CASCADE ); CREATE TABLE Abonnement ( @@ -44,7 +44,7 @@ CREATE TABLE Abonnement ( dateAbonnement TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT pk_abonnement PRIMARY KEY (utilisateurEmail, filId), CONSTRAINT fk_utilisateur FOREIGN KEY (utilisateurEmail) REFERENCES Utilisateur(email) - ON DELETE CASCADE, + ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_fil FOREIGN KEY (filId) REFERENCES FilDeDiscussion(id) ON DELETE CASCADE ); -- GitLab