diff --git a/commons-lang3-3.17.0.jar b/commons-lang3-3.17.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..f6486b4d7039f22ccf160c8d24ebac26f05bf0de Binary files /dev/null and b/commons-lang3-3.17.0.jar differ diff --git a/commons-text-1.13.0.jar b/commons-text-1.13.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..a8231464949d5e7fb71a14e044767ad1bfa4c27d Binary files /dev/null and b/commons-text-1.13.0.jar differ diff --git a/compilation.md b/compilation.md index 2b7338c6331de035a1c2d5f8474753ea18227e36..d8793aa08373aa217d970999e69be7adc10f7687 100644 --- a/compilation.md +++ b/compilation.md @@ -1 +1 @@ -javac -d WEB-INF/classes -cp ../../lib/servlet-api.jar WEB-INF/src/controleur/*.java WEB-INF/src/modele/*.java \ No newline at end of file +javac -d WEB-INF/classes -cp ../../lib/servlet-api.jar:../../lib/commons-lang3-3.17.0.jar:../../lib/commons-text-1.13.0.jar WEB-INF/src/controleur/*.java WEB-INF/src/modele/*.java \ No newline at end of file diff --git a/sae/WEB-INF/src/controleur/Accueil.java b/sae/WEB-INF/src/controleur/Accueil.java index 532f6c3d3562ed9975c35f9e5b7257bf7c8998fc..1524c2f3bcfe5c353fe7e94f3feff9e6bfe17497 100644 --- a/sae/WEB-INF/src/controleur/Accueil.java +++ b/sae/WEB-INF/src/controleur/Accueil.java @@ -7,17 +7,19 @@ import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; +import org.apache.commons.text.StringEscapeUtils; @WebServlet("/accueil") public class Accueil extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - HttpSession session = request.getSession(false); - if (session != null && session.getAttribute("email") != null) { - request.getRequestDispatcher("/WEB-INF/vue/accueil.jsp").forward(request, response); - } else { - System.out.println("Accès refusé"); + if (request.getSession(false) == null || request.getSession().getAttribute("email") == null) { response.sendRedirect(request.getContextPath() + "/login"); + return; } + HttpSession session = request.getSession(); + String email = StringEscapeUtils.escapeHtml4((String) session.getAttribute("email")); + request.setAttribute("email", email); + request.getRequestDispatcher("/WEB-INF/vue/accueil.jsp").forward(request, response); } -} \ No newline at end of file +} diff --git a/sae/WEB-INF/src/controleur/CreationFil.java b/sae/WEB-INF/src/controleur/CreerFil.java similarity index 54% rename from sae/WEB-INF/src/controleur/CreationFil.java rename to sae/WEB-INF/src/controleur/CreerFil.java index 416f321cb440befe8a308fc2189ac1beebb6ed22..9e31e62023732982e498956d7a58721c3fb8e736 100644 --- a/sae/WEB-INF/src/controleur/CreationFil.java +++ b/sae/WEB-INF/src/controleur/CreerFil.java @@ -10,25 +10,31 @@ import modele.FilDeDiscussion; import modele.FilDeDiscussionDAO; import jakarta.servlet.ServletException; import java.io.IOException; +import org.apache.commons.text.StringEscapeUtils; -@WebServlet("/creationFil") -public class CreationFil extends HttpServlet { +@WebServlet("/creerFil") +public class CreerFil extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { - req.getRequestDispatcher("/WEB-INF/vue/creationFil.jsp").forward(req, res); + if (req.getSession(false) == null || req.getSession().getAttribute("email") == null) { + res.sendRedirect(req.getContextPath() + "/login"); + return; + } + req.getRequestDispatcher("/WEB-INF/vue/creerFil.jsp").forward(req, res); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { FilDeDiscussionDAO f = new FilDeDiscussionDAO(); + String nom = StringEscapeUtils.escapeHtml4(req.getParameter("nom")); + String createuremail = StringEscapeUtils.escapeHtml4(req.getParameter("createuremail")); f.create(new FilDeDiscussion( -1, - req.getParameter("nom"), + nom, LocalDateTime.now(), - req.getParameter("createuremail") + createuremail )); - - res.sendRedirect(req.getContextPath() + "/creationFil"); + res.sendRedirect(req.getContextPath() + "/listerFil"); } } diff --git a/sae/WEB-INF/src/controleur/EnvoyerMessage.java b/sae/WEB-INF/src/controleur/EnvoyerMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..2fcaea9936d1ae2c8b720da8f193fc417f57c31b --- /dev/null +++ b/sae/WEB-INF/src/controleur/EnvoyerMessage.java @@ -0,0 +1,39 @@ +package controleur; + +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import modele.Message; +import modele.MessageDao; +import jakarta.servlet.ServletException; +import java.io.IOException; +import java.time.LocalDateTime; + +@WebServlet("/envoyerMessage") +public class EnvoyerMessage extends HttpServlet { + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + if (req.getSession(false) == null || req.getSession().getAttribute("email") == null) { + res.sendRedirect(req.getContextPath() + "/login"); + return; + } + req.getRequestDispatcher("/WEB-INF/vue/listeFil.jsp").forward(req, res); + } + + public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + if (req.getSession(false) == null || req.getSession().getAttribute("email") == null) { + res.sendRedirect(req.getContextPath() + "/login"); + return; + } + String email = (String) req.getSession().getAttribute("email"); + String message = req.getParameter("contenu"); + int filId = (int) req.getSession().getAttribute("filId"); + if (message == null || message.isEmpty()) { + return; + } + Message m = new Message(-1, message, LocalDateTime.now(), filId, email); + modele.MessageDao messageDao = new MessageDao(); + messageDao.create(m); + res.sendRedirect(req.getContextPath() + "/fil?id=" + filId); + } +} diff --git a/sae/WEB-INF/src/controleur/Fil.java b/sae/WEB-INF/src/controleur/Fil.java index 7ae208eddddf6bbd398167c13aca1c59aa645f91..bb63417d975494220d33fe9b30f38366d2572bd8 100644 --- a/sae/WEB-INF/src/controleur/Fil.java +++ b/sae/WEB-INF/src/controleur/Fil.java @@ -4,15 +4,24 @@ import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import modele.AbonnementDao; import jakarta.servlet.ServletException; import java.io.IOException; @WebServlet("/fil") public class Fil extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { - // si la personne n'est pas abonnée à ce fil, on la redirige vers la page de liste des fils - // TODO + if (req.getSession(false) == null || req.getSession().getAttribute("email") == null) { + res.sendRedirect(req.getContextPath() + "/login"); + return; + } int id = Integer.parseInt(req.getParameter("id")); + String email = (String) req.getSession().getAttribute("email"); + // AbonnementDao abonnementDao = new AbonnementDao(); + // if (!abonnementDao.isAbonne(email, id)) { + // res.sendRedirect(req.getContextPath() + "/listerFil"); + // return; + // } req.setAttribute("id", id); req.getRequestDispatcher("/WEB-INF/vue/fil.jsp").forward(req, res); } diff --git a/sae/WEB-INF/src/controleur/Login.java b/sae/WEB-INF/src/controleur/Login.java index e79e71809b9ecd070dd79bccdae731a99eefa666..655e8dbb40cb8152949600a0c312e3086e607715 100644 --- a/sae/WEB-INF/src/controleur/Login.java +++ b/sae/WEB-INF/src/controleur/Login.java @@ -4,10 +4,10 @@ import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.http.HttpSession; import modele.UtilisateurDao; import jakarta.servlet.ServletException; import java.io.IOException; +import org.apache.commons.text.StringEscapeUtils; @WebServlet("/login") public class Login extends HttpServlet { @@ -16,8 +16,8 @@ public class Login extends HttpServlet { } public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { - String email = req.getParameter("email"); - String motdepasse = req.getParameter("motdepasse"); + String email = StringEscapeUtils.escapeHtml4(req.getParameter("email")); + String motdepasse = StringEscapeUtils.escapeHtml4(req.getParameter("motdepasse")); UtilisateurDao udao = new UtilisateurDao(); if (udao.check(email, motdepasse)) { System.out.println("Connexion réussie"); diff --git a/sae/WEB-INF/src/controleur/Register.java b/sae/WEB-INF/src/controleur/Register.java index 8cded3d8ebd138c1f620a3b1d381c789ca87164b..4506f6a55285d3dd8623d23d4324df3b48d2bd84 100644 --- a/sae/WEB-INF/src/controleur/Register.java +++ b/sae/WEB-INF/src/controleur/Register.java @@ -9,6 +9,7 @@ import jakarta.servlet.ServletException; import java.io.IOException; import modele.Utilisateur; import modele.UtilisateurDao; +import org.apache.commons.text.StringEscapeUtils; @WebServlet("/register") public class Register extends HttpServlet { @@ -21,12 +22,21 @@ public class Register extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { UtilisateurDao udao = new UtilisateurDao(); - udao.insert(new Utilisateur( - req.getParameter("nom"), - req.getParameter("email"), - req.getParameter("motdepasse"), + String email = StringEscapeUtils.escapeHtml4(req.getParameter("email")); + String motdepasse = StringEscapeUtils.escapeHtml4(req.getParameter("motdepasse")); + String nom = StringEscapeUtils.escapeHtml4(req.getParameter("nom")); + if (udao.emailExists(email)) { + req.setAttribute("error", "L'email est déjà utilisé."); + req.getRequestDispatcher("/WEB-INF/vue/register.jsp").forward(req, res); + } else { + udao.insert(new Utilisateur( + nom, + email, + motdepasse, LocalDateTime.now() - )); - res.sendRedirect(req.getContextPath() + "/login.jsp"); + )); + req.getSession().setAttribute("email", email); + res.sendRedirect(req.getContextPath() + "/accueil"); + } } } diff --git a/sae/WEB-INF/src/controleur/SuivreFil.java b/sae/WEB-INF/src/controleur/SuivreFil.java new file mode 100644 index 0000000000000000000000000000000000000000..80db4396706fbb14407fd2fc5f9e5c8607876ff0 --- /dev/null +++ b/sae/WEB-INF/src/controleur/SuivreFil.java @@ -0,0 +1,24 @@ +package controleur; + +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import modele.AbonnementDao; +import jakarta.servlet.ServletException; +import java.io.IOException; + +@WebServlet("/suivreFil") +public class SuivreFil extends HttpServlet { + public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + if (req.getSession(false) == null || req.getSession().getAttribute("email") == null) { + res.sendRedirect(req.getContextPath() + "/login"); + return; + } + int id = Integer.parseInt(req.getParameter("id")); + String email = (String) req.getSession().getAttribute("email"); + AbonnementDao adao = new AbonnementDao(); + adao.abonner(email, id); + req.getRequestDispatcher("/WEB-INF/vue/listerFil.jsp").forward(req, res); + } +} \ No newline at end of file diff --git a/sae/WEB-INF/src/modele/AbonnementDao.java b/sae/WEB-INF/src/modele/AbonnementDao.java index 7613030500e0f485a99031d2771e60335ca15c9b..151db56f829371b350e8ac9b0be21c0da1e0a84d 100644 --- a/sae/WEB-INF/src/modele/AbonnementDao.java +++ b/sae/WEB-INF/src/modele/AbonnementDao.java @@ -11,14 +11,14 @@ public class AbonnementDao { public Abonnement findAbonnement(String utilisateurEmail, int idFil) { Abonnement abonnement = new Abonnement(); try(Connection con = DS.instance.getConnection()) { - PreparedStatement ps = con.prepareStatement("SELECT * FROM abonnement WHERE utilisateurEmail = ? AND idFil = ?"); + PreparedStatement ps = con.prepareStatement("SELECT * FROM abonnement WHERE utilisateuremail = ? AND filid = ?"); ps.setString(1, utilisateurEmail); ps.setInt(2, idFil); ResultSet rs = ps.executeQuery(); if (rs.next()) { - abonnement.setUtilisateurEmail(rs.getString("utilisateurEmail")); - abonnement.setIdFil(rs.getInt("idFil")); - abonnement.setDateAbonnement(rs.getDate("dateAbonnement").toLocalDate()); + abonnement.setUtilisateurEmail(rs.getString("utilisateuremail")); + abonnement.setIdFil(rs.getInt("filid")); + abonnement.setDateAbonnement(rs.getDate("dateabonnement").toLocalDate()); } else { System.out.println("Abonnement inexistant"); } @@ -35,9 +35,9 @@ public class AbonnementDao { ResultSet rs = ps.executeQuery(); while (rs.next()) { Abonnement abonnement = new Abonnement(); - abonnement.setUtilisateurEmail(rs.getString("utilisateurEmail")); - abonnement.setIdFil(rs.getInt("idFil")); - abonnement.setDateAbonnement(rs.getDate("dateAbonnement").toLocalDate()); + abonnement.setUtilisateurEmail(rs.getString("utilisateuremail")); + abonnement.setIdFil(rs.getInt("filid")); + abonnement.setDateAbonnement(rs.getDate("dateabonnement").toLocalDate()); abonnements.add(abonnement); } } catch (Exception e) { @@ -49,14 +49,14 @@ public class AbonnementDao { public List<Abonnement> findAbonnements(String utilisateurEmail) { List<Abonnement> abonnements = new ArrayList<>(); try(Connection con = DS.instance.getConnection()) { - PreparedStatement ps = con.prepareStatement("SELECT * FROM abonnement WHERE utilisateurEmail = ?"); + PreparedStatement ps = con.prepareStatement("SELECT * FROM abonnement WHERE utilisateuremail = ?"); ps.setString(1, utilisateurEmail); ResultSet rs = ps.executeQuery(); while (rs.next()) { Abonnement abonnement = new Abonnement(); - abonnement.setUtilisateurEmail(rs.getString("utilisateurEmail")); - abonnement.setIdFil(rs.getInt("idFil")); - abonnement.setDateAbonnement(rs.getDate("dateAbonnement").toLocalDate()); + abonnement.setUtilisateurEmail(rs.getString("utilisateuremail")); + abonnement.setIdFil(rs.getInt("filid")); + abonnement.setDateAbonnement(rs.getDate("dateabonnement").toLocalDate()); abonnements.add(abonnement); } } catch (Exception e) { @@ -64,4 +64,28 @@ public class AbonnementDao { } return abonnements; } + + public boolean isAbonne(String utilisateurEmail, int idFil) { + try(Connection con = DS.instance.getConnection()) { + PreparedStatement ps = con.prepareStatement("SELECT * FROM abonnement WHERE utilisateuremail = ? AND filid = ?"); + ps.setString(1, utilisateurEmail); + ps.setInt(2, idFil); + ResultSet rs = ps.executeQuery(); + return rs.next(); + } catch (Exception e) { + System.out.println(e.getMessage()); + return false; + } + } + + public void abonner(String utilisateurEmail, int idFil) { + try(Connection con = DS.instance.getConnection()) { + PreparedStatement pstmt = con.prepareStatement("INSERT INTO abonnement (utilisateuremail, filid) VALUES (?, ?)"); + pstmt.setString(1, utilisateurEmail); + pstmt.setInt(2, idFil); + pstmt.executeUpdate(); + } catch (Exception e) { + System.err.println(e.getMessage()); + } + } } diff --git a/sae/WEB-INF/src/modele/FilDeDiscussionDAO.java b/sae/WEB-INF/src/modele/FilDeDiscussionDAO.java index e869736b2f80d0e4b0024b68cd1b7197724f8406..1fdd43bb9a18bb46c22cbd0f421d14226eb13926 100644 --- a/sae/WEB-INF/src/modele/FilDeDiscussionDAO.java +++ b/sae/WEB-INF/src/modele/FilDeDiscussionDAO.java @@ -17,8 +17,8 @@ public class FilDeDiscussionDAO { if (rs.next()) { f.setId(rs.getInt("id")); f.setNom(rs.getString("nom")); - f.setDateCreation(rs.getTimestamp("dateCreation").toLocalDateTime()); - f.setCreateurEmail(rs.getString("createurEmail")); + f.setDateCreation(rs.getTimestamp("datecreation").toLocalDateTime()); + f.setCreateurEmail(rs.getString("createuremail")); } else { System.out.println("Fil de discussion inexistant"); } @@ -30,7 +30,7 @@ public class FilDeDiscussionDAO { public void create(FilDeDiscussion filDeDiscussion) { try (Connection con = DS.instance.getConnection()) { - PreparedStatement pstmt = con.prepareStatement("INSERT INTO filDeDiscussion (nom, createurEmail) VALUES (?, ?)"); + PreparedStatement pstmt = con.prepareStatement("INSERT INTO filDeDiscussion (nom, createuremail) VALUES (?, ?)"); pstmt.setString(1, filDeDiscussion.getNom()); pstmt.setString(2, filDeDiscussion.getCreateurEmail()); pstmt.executeUpdate(); @@ -48,8 +48,8 @@ public class FilDeDiscussionDAO { FilDeDiscussion f = new FilDeDiscussion(); f.setId(rs.getInt("id")); f.setNom(rs.getString("nom")); - f.setDateCreation(rs.getTimestamp("dateCreation").toLocalDateTime()); - f.setCreateurEmail(rs.getString("createurEmail")); + f.setDateCreation(rs.getTimestamp("datecreation").toLocalDateTime()); + f.setCreateurEmail(rs.getString("createuremail")); filsDeDiscussion.add(f); } } catch (Exception e) { @@ -67,5 +67,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 97006a6eac65c733c1ee00ca35878afb8919cd02..4ae3ecbd967411e16ba04996b3c60afe80659c7b 100644 --- a/sae/WEB-INF/src/modele/MessageDao.java +++ b/sae/WEB-INF/src/modele/MessageDao.java @@ -86,4 +86,26 @@ public class MessageDao { } return userName; } + + public void delete(int id) { + try(Connection con = DS.instance.getConnection()) { + PreparedStatement ps = con.prepareStatement("DELETE FROM message WHERE id = ?"); + ps.setInt(1, id); + ps.executeUpdate(); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + + public void create(Message message) { + try(Connection con = DS.instance.getConnection()) { + PreparedStatement ps = con.prepareStatement("INSERT INTO message (contenu, filid, auteuremail) VALUES (?, ?, ?)"); + ps.setString(1, message.getContenu()); + ps.setInt(2, message.getfilId()); + ps.setString(3, message.getAuteurEmail()); + ps.executeUpdate(); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } } diff --git a/sae/WEB-INF/src/modele/UtilisateurDao.java b/sae/WEB-INF/src/modele/UtilisateurDao.java index ee5243c9c92e17fc7a3fc98357c990626108a1c4..cb0fce656bb3582a96ad445fcb1cdb15fda75383 100644 --- a/sae/WEB-INF/src/modele/UtilisateurDao.java +++ b/sae/WEB-INF/src/modele/UtilisateurDao.java @@ -15,8 +15,8 @@ public class UtilisateurDao { if (rs.next()) { utilisateur.setNom(rs.getString("nom")); utilisateur.setEmail(rs.getString("email")); - utilisateur.setMotDePasse(rs.getString("motDePasse")); - utilisateur.setDateInscription(rs.getTimestamp("dateInscritpion").toLocalDateTime()); + utilisateur.setMotDePasse(rs.getString("motdepasse")); + utilisateur.setDateInscription(rs.getTimestamp("dateinscription").toLocalDateTime()); } else { System.out.println("Utilisateur inexistant"); } @@ -26,6 +26,18 @@ public class UtilisateurDao { return utilisateur; } + public boolean emailExists(String email) { + try(Connection con = DS.instance.getConnection()) { + PreparedStatement ps = con.prepareStatement("SELECT * FROM Utilisateur WHERE email = ?"); + ps.setString(1, email); + ResultSet rs = ps.executeQuery(); + return rs.next(); + } catch (Exception e) { + System.out.println(e.getMessage()); + return false; + } + } + public void delete(String email) { try(Connection con = DS.instance.getConnection()) { PreparedStatement ps = con.prepareStatement("DELETE FROM Utilisateur WHERE email = ?"); @@ -38,7 +50,7 @@ public class UtilisateurDao { public void update(Utilisateur utilisateur) { try(Connection con = DS.instance.getConnection()) { - PreparedStatement ps = con.prepareStatement("UPDATE Utilisateur SET nom = ?, email = ?, motDePasse = ? WHERE email = ?"); + 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()); @@ -50,7 +62,7 @@ public class UtilisateurDao { public void insert(Utilisateur utilisateur) { try(Connection con = DS.instance.getConnection()) { - PreparedStatement ps = con.prepareStatement("INSERT INTO Utilisateur (nom, email, motDePasse) VALUES (?, ?, MD5(?))"); + PreparedStatement ps = con.prepareStatement("INSERT INTO Utilisateur (nom, email, motdepasse) VALUES (?, ?, MD5(?))"); ps.setString(1, utilisateur.getNom()); ps.setString(2, utilisateur.getEmail()); ps.setString(3, utilisateur.getMotDePasse()); @@ -62,7 +74,7 @@ public class UtilisateurDao { public boolean check(String email, String motDePasse) { try(Connection con = DS.instance.getConnection()) { - PreparedStatement ps = con.prepareStatement("SELECT * FROM Utilisateur WHERE email = ? AND motDePasse = MD5(?)"); + PreparedStatement ps = con.prepareStatement("SELECT * FROM Utilisateur WHERE email = ? AND motdepasse = MD5(?)"); ps.setString(1, email); ps.setString(2, motDePasse); ResultSet rs = ps.executeQuery(); diff --git a/sae/WEB-INF/vue/accueil.jsp b/sae/WEB-INF/vue/accueil.jsp index e9df037c56c7c6ad4d7478af16bf6a74e3252e37..b04dad2e67e28c09d877b634f2c8ccd5e1188323 100644 --- a/sae/WEB-INF/vue/accueil.jsp +++ b/sae/WEB-INF/vue/accueil.jsp @@ -1,4 +1,5 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ page import="modele.UtilisateurDao" %> <!DOCTYPE html> <html lang="fr"> @@ -7,6 +8,7 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CampusTalk - Accueil</title> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> + <link rel="shortcut icon" href="https://www.shareicon.net/data/2016/07/10/119195_chat_512x512.png"> <style> body { background-color: #f8f9fa; @@ -26,17 +28,29 @@ </style> </head> <body> - <div class="welcome-container"> - <h2 class="text-center">Bienvenue sur CampusTalk</h2> - <p class="text-center">Bonjour, <%= session.getAttribute("email") %> !</p> - <p class="text-center">Vous êtes connecté en tant que <%= session.getAttribute("email") %></p> - <div class="text-center mt-4"> - <a href="<%= request.getContextPath() %>/logout" class="btn btn-danger">Se déconnecter</a> + <nav class="navbar navbar-expand-lg navbar-light bg-light"> + <a class="navbar-brand" href="#">CampusTalk</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbarNav"> + <ul class="navbar-nav ml-auto"> + <li class="nav-item"> + <a class="nav-link btn btn-danger text-white" href="<%= request.getContextPath() %>/logout">Se déconnecter</a> + </li> + </ul> </div> + </nav> + <% + UtilisateurDao udao = new UtilisateurDao(); + String username = udao.findUtilisateur((String) session.getAttribute("email")).getNom(); + %> + <div class="welcome-container text-center"> + <h2>Bienvenue sur CampusTalk</h2> + <p>Bonjour, <%= username %> !</p> + <p>Vous êtes connecté en tant que <%= session.getAttribute("email") %></p> + <a href="<%= request.getContextPath() %>/listerFil" class="btn btn-primary mt-4">Voir les fils de discussion</a> </div> - <button type="button" class="btn btn-primary mt-4 mx-auto d-block"> - <a href="<%= request.getContextPath() %>/listerFil" style="color: white; text-decoration: none;">Voir les fils de discussion</a> - </button> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script> diff --git a/sae/WEB-INF/vue/creationFil.jsp b/sae/WEB-INF/vue/creationFil.jsp deleted file mode 100644 index 19a38cc5c9b4919efc84d31c22488fa381cdcbb9..0000000000000000000000000000000000000000 --- a/sae/WEB-INF/vue/creationFil.jsp +++ /dev/null @@ -1,28 +0,0 @@ -<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> - -<!DOCTYPE html> -<html lang="fr"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Liste des Fils</title> - <!-- Bootstrap CSS --> - <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> -</head> -<body> - <div class="container"> - <h1 class="mt-5">Créer un nouveau fil de discussion</h1> - <form action="creationFil" method="post" class="mt-4"> - <div class="form-group"> - <label for="nom">Nom du fil:</label> - <input type="text" class="form-control" id="nom" name="nom" required> - </div> - <div class="form-group"> - <label for="createuremail">Email du créateur:</label> - <input type="text" class="form-control" id="createuremail" name="createuremail"> - </div> - <button type="submit" class="btn btn-primary">Créer</button> - </form> - </div> -</body> -</html> diff --git a/sae/WEB-INF/vue/creerFil.jsp b/sae/WEB-INF/vue/creerFil.jsp new file mode 100644 index 0000000000000000000000000000000000000000..b95276236515684f1732a71fea86374828a68d3a --- /dev/null +++ b/sae/WEB-INF/vue/creerFil.jsp @@ -0,0 +1,68 @@ +<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> + +<!DOCTYPE html> +<html lang="fr"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>CampusTalk - Créer un Fil de Discussion</title> + <!-- Bootstrap CSS --> + <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> + <link rel="shortcut icon" href="https://www.shareicon.net/data/2016/07/10/119195_chat_512x512.png"> + <style> + body { + background-color: #f8f9fa; + } + .form-container { + max-width: 600px; + margin: 50px auto; + padding: 20px; + background-color: #ffffff; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + } + .form-container h1 { + margin-bottom: 20px; + font-weight: bold; + } + </style> +</head> +<body> + <nav class="navbar navbar-expand-lg navbar-light bg-light"> + <a class="navbar-brand" href="#">CampusTalk</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbarNav"> + <ul class="navbar-nav ml-auto"> + <li class="nav-item"> + <a class="nav-link btn btn-danger text-white" href="<%= request.getContextPath() %>/logout">Se déconnecter</a> + </li> + </ul> + </div> + </nav> + <div class="container"> + <div class="text-center mb-4"> + <a href="<%= request.getContextPath() %>/listerFil" class="btn btn-primary">Retour aux fils de discussion</a> + </div> + <div class="form-container"> + <h1 class="text-center">Créer un nouveau fil de discussion</h1> + <form action="creerFil" method="post" class="mt-4"> + <div class="form-group"> + <label for="nom">Nom du fil:</label> + <input type="text" class="form-control" id="nom" name="nom" required> + </div> + <div class="form-group"> + <label for="createuremail">Email du créateur:</label> + <input type="email" class="form-control" id="createuremail" name="createuremail" required> + </div> + <button type="submit" class="btn btn-primary btn-block">Créer</button> + </form> + </div> + </div> + + <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> + <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script> + <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> +</body> +</html> \ No newline at end of file diff --git a/sae/WEB-INF/vue/fil.jsp b/sae/WEB-INF/vue/fil.jsp index e708b7665446f6da3b80466abc15af65fe673df3..d19505d3b29dc34241b13628b7f46a6d394a21e9 100644 --- a/sae/WEB-INF/vue/fil.jsp +++ b/sae/WEB-INF/vue/fil.jsp @@ -4,6 +4,8 @@ <%@ page import="modele.Message" %> <%@ page import="modele.MessageDao" %> <%@ page import="java.util.List" %> +<%@ page import="java.time.LocalDateTime" %> +<%@ page import="java.time.format.DateTimeFormatter" %> <!DOCTYPE html> <html lang="fr"> @@ -12,9 +14,19 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CampusTalk - Fil de Discussion</title> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> + <link rel="shortcut icon" href="https://www.shareicon.net/data/2016/07/10/119195_chat_512x512.png"> <style> body { background-color: #f8f9fa; + color: #212529; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + } + .navbar { + background-color: #ffffff; + border-bottom: 1px solid #e0e0e0; + } + .navbar-brand, .nav-link { + color: #212529 !important; } .thread-container { max-width: 800px; @@ -27,71 +39,139 @@ .thread-container h2 { margin-bottom: 20px; font-weight: bold; + color: #212529; + } + .messages-box { + max-height: 400px; + overflow-y: auto; + padding-right: 15px; } .message-item { display: flex; align-items: flex-start; - padding: 10px; - border-bottom: 1px solid #ddd; + padding: 10px 0; + border-bottom: 1px solid #e0e0e0; } .message-item:last-child { border-bottom: none; } .avatar { - width: 50px; - height: 50px; + width: 40px; + height: 40px; border-radius: 50%; - margin-right: 15px; + margin-right: 10px; } .message-content { - background-color: #e9ecef; + background-color: #f1f1f1; padding: 10px; border-radius: 10px; max-width: 600px; + color: #212529; } .message-content h4 { margin: 0; - font-size: 1.1em; + font-size: 1em; font-weight: bold; + color: #212529; } .message-content p { - margin: 5px 0; + margin: 3px 0; } .message-date { font-size: 0.8em; color: #6c757d; } + .message-form { + margin-top: 20px; + padding: 20px; + border-top: 1px solid #e0e0e0; + } + .message-form label { + color: #212529; + } + .message-form textarea { + background-color: #f1f1f1; + color: #212529; + border: 1px solid #e0e0e0; + } + .message-form button { + background-color: #007bff; + border: none; + color: #ffffff; + } + .message-form button:hover { + background-color: #0056b3; + } </style> </head> <body> + <nav class="navbar navbar-expand-lg"> + <a class="navbar-brand" href="#">CampusTalk</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbarNav"> + <ul class="navbar-nav ml-auto"> + <li class="nav-item"> + <a class="nav-link btn btn-danger text-white" href="<%= request.getContextPath() %>/logout">Se déconnecter</a> + </li> + </ul> + </div> + </nav> <div class="text-center mt-4"> <a href="<%= request.getContextPath() %>/listerFil" class="btn btn-primary">Retour</a> </div> - <% + <% int id = Integer.parseInt(request.getParameter("id")); + session.setAttribute("filId", id); FilDeDiscussionDAO fddao = new FilDeDiscussionDAO(); FilDeDiscussion fil = fddao.findById(id); MessageDao mdao = new MessageDao(); List<Message> messages = mdao.findByFil(id); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy 'à' HH:mm"); %> - + <div class="thread-container"> <h2 class="text-center"><%= fil.getNom() %></h2> - <% for (Message m : messages) { %> - <div class="message-item"> - <!-- potentiellement une pdp --> - <div class="message-content"> - <h4><%= mdao.findUserName(m.getAuteurEmail()) %></h4> - <p class="message-date"><%= m.getDatePublication() %></p> - <p><%= m.getContenu() %></p> + <div class="messages-box" id="messages-box"> + <% for (Message m : messages) { + LocalDateTime datePublication = m.getDatePublication(); + String formattedDate = (datePublication != null) ? datePublication.format(formatter) : "Date non disponible"; + %> + <div class="message-item"> + <div class="avatar"> + <img src="https://www.gravatar.com/avatar/<%= m.getAuteurEmail().hashCode() %>?d=identicon&s=40" alt="Avatar"> + </div> + <div class="message-content"> + <h4><%= mdao.findUserName(m.getAuteurEmail()) %></h4> + <p class="message-date"><%= formattedDate %></p> + <p><%= m.getContenu() %></p> + </div> + </div> + <% } %> + </div> + + <div class="message-form"> + <form action="envoyerMessage" method="post"> + <div class="form-group"> + <label for="contenu">Votre message :</label> + <textarea class="form-control" id="contenu" name="contenu" rows="3" required></textarea> </div> - </div> - <% } %> + <input type="hidden" name="filId" value="<%= id %>"> + <button type="submit" class="btn btn-primary">Envoyer</button> + </form> + </div> </div> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> + <script> + window.onload = function() { + let messagesBox = document.getElementById('messages-box'); + messagesBox.scrollTop = messagesBox.scrollHeight; + }; + </script> </body> </html> \ No newline at end of file diff --git a/sae/WEB-INF/vue/listerFil.jsp b/sae/WEB-INF/vue/listerFil.jsp index 79f64af8ae23136490a936e050b72af014bb405e..9dab6a0ae78a410ea2d99ba9322ef7c98fc789f8 100644 --- a/sae/WEB-INF/vue/listerFil.jsp +++ b/sae/WEB-INF/vue/listerFil.jsp @@ -9,6 +9,7 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CampusTalk - Fils de Discussion</title> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> + <link rel="shortcut icon" href="https://www.shareicon.net/data/2016/07/10/119195_chat_512x512.png"> <style> body { background-color: #f8f9fa; @@ -32,20 +33,48 @@ .thread-item:last-child { border-bottom: none; } + .navbar { + margin-bottom: 20px; + } + .btn-primary, .btn-danger { + margin: 5px; + } </style> </head> <body> - <div class="thread-container"> - <h2 class="text-center">Fils de Discussion</h2> - <% - FilDeDiscussionDAO fddao = new FilDeDiscussionDAO(); - for (FilDeDiscussion f : fddao.findAll()) { - %> - <div class="thread-item"> - <h4><a href="<%= request.getContextPath() %>/fil?id=<%= f.getId() %>"><%= f.getNom() %></a></h4> - <!-- potentiellement mettre une description --> - </div> - <% } %> + <nav class="navbar navbar-expand-lg navbar-light bg-light"> + <a class="navbar-brand" href="#">CampusTalk</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbarNav"> + <ul class="navbar-nav ml-auto"> + <li class="nav-item"> + <a class="nav-link btn btn-danger text-white" href="<%= request.getContextPath() %>/logout">Se déconnecter</a> + </li> + </ul> + </div> + </nav> + <div class="container"> + <div class="text-center mb-4"> + <a href="<%= request.getContextPath() %>/accueil" class="btn btn-primary">Retour à l'accueil</a> + <a href="<%= request.getContextPath() %>/creerFil" class="btn btn-primary">Créer un fil de discussion</a> + </div> + <div class="thread-container"> + <h2 class="text-center">Fils de Discussion</h2> + <% + FilDeDiscussionDAO fddao = new FilDeDiscussionDAO(); + for (FilDeDiscussion f : fddao.findAll()) { + %> + <div class="thread-item"> + <h4> + <a href="<%= request.getContextPath() %>/fil?id=<%= f.getId() %>"><%= f.getNom() %></a> + <!-- <a href="<%= request.getContextPath() %>/suivreFil?id=<%= f.getId() %>" class="btn btn-primary btn-sm float-right">Suivre</a> --> + </h4> + <!-- potentiellement mettre une description --> + </div> + <% } %> + </div> </div> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> diff --git a/sae/WEB-INF/vue/login.jsp b/sae/WEB-INF/vue/login.jsp index ea730405671484d9ed873a3d2eb6ad2c100dee79..0d06c71265a2fa165509eea5c36a5159f8d1638a 100644 --- a/sae/WEB-INF/vue/login.jsp +++ b/sae/WEB-INF/vue/login.jsp @@ -5,8 +5,9 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>CampusTalk - Accueil</title> + <title>CampusTalk - Connexion</title> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> + <link rel="shortcut icon" href="https://www.shareicon.net/data/2016/07/10/119195_chat_512x512.png"> <style> body { background-color: #f8f9fa; @@ -26,9 +27,14 @@ </style> </head> <body> + <nav class="navbar navbar-expand-lg navbar-light bg-light"> + <a class="navbar-brand" href="#">CampusTalk</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + </nav> <div class="login-container"> <h2 class="text-center">Bienvenue sur CampusTalk</h2> - <!-- formulaire pour se connecter --> <form action="login" method="post"> <div class="form-group"> <label for="email">Adresse e-mail</label> diff --git a/sae/WEB-INF/vue/register.jsp b/sae/WEB-INF/vue/register.jsp index 0a2f1c192a9b44bfa5e57eca80d72854059bf748..2a9122247f6920761a46e742fcdf952dacfd408c 100644 --- a/sae/WEB-INF/vue/register.jsp +++ b/sae/WEB-INF/vue/register.jsp @@ -1,4 +1,4 @@ -<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE html> <html lang="fr"> @@ -7,6 +7,7 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CampusTalk - Inscription</title> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> + <link rel="shortcut icon" href="https://www.shareicon.net/data/2016/07/10/119195_chat_512x512.png"> <style> body { background-color: #f8f9fa; @@ -26,10 +27,21 @@ </style> </head> <body> + <nav class="navbar navbar-expand-lg navbar-light bg-light"> + <a class="navbar-brand" href="#">CampusTalk</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + </nav> <div class="register-container"> <h2 class="text-center">Inscription</h2> - <!-- Formulaire pour s'inscrire --> - <form action="ajoutUtilisateur" method="post"> + <% if (request.getAttribute("error") != null) { %> + <div class="alert alert-danger" role="alert"> + <%= request.getAttribute("error") %> + </div> + <% request.removeAttribute("error"); + } %> + <form action="register" method="post"> <div class="form-group"> <label for="nom">Nom</label> <input type="text" class="form-control" name="nom" id="nom" placeholder="Entrez votre nom" required>