mirror of
https://github.com/kmitresse/Cards-Rush.git
synced 2026-05-17 01:21:48 +00:00
feat!(DevWeb): Add BulmaCSS, refacto, handle error on login pages, use bean, filters and tags
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<%@ page import="uppa.project.pojo.User" %>
|
||||
<%@ page import="uppa.project.database.pojo.User" %>
|
||||
<%@ page pageEncoding="UTF-8" %>
|
||||
<%--
|
||||
Created by IntelliJ IDEA.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<%@ page import="uppa.project.pojo.User" %>
|
||||
<%@ page import="uppa.project.pojo.Game" %>
|
||||
<%@ page import="uppa.project.pojo.Deck" %>
|
||||
<%@ page import="uppa.project.database.pojo.User" %>
|
||||
<%@ page import="uppa.project.database.pojo.Game" %>
|
||||
<%@ page import="uppa.project.database.pojo.Deck" %>
|
||||
<%@ page pageEncoding="UTF-8" %>
|
||||
|
||||
<div id="newGameModal" class="modal-wrapper" style="display: none">
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<%@ page import="uppa.project.pojo.User" %>
|
||||
<%@ page import="uppa.project.pojo.Game" %>
|
||||
<%@ page import="uppa.project.database.pojo.User" %>
|
||||
<%@ page import="uppa.project.database.pojo.Game" %>
|
||||
<%@ page import="java.util.ArrayList" %>
|
||||
<%@ page import="uppa.project.pojo.Player" %>
|
||||
<%@ page import="uppa.project.database.pojo.Player" %>
|
||||
<%@ page import="java.util.Date" %>
|
||||
<%@ page pageEncoding="UTF-8" %>
|
||||
|
||||
|
||||
<%--TODO: adapter les deux lignes suivante pour ne pas vérifier la valeur nulle--%>
|
||||
<% User user = (User) session.getAttribute("user") != null ? (User) session.getAttribute("user") : new User("toto", "toto@gmail.com", "totopassword", new Date(), User.Gender.MALE); %>
|
||||
<% User user = session.getAttribute("user") != null ? (User) session.getAttribute("user") : new User("toto", "toto@gmail.com", "totopassword", new Date(), User.Gender.MALE); %>
|
||||
<% ArrayList<Game> games = (ArrayList<Game>) request.getAttribute("games") != null ? (ArrayList<Game>) request.getAttribute("games") : new ArrayList<>() ; %>
|
||||
<div id="statisticsModal" class="modal-wrapper" style="display: none">
|
||||
<div class="modal">
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
<body>
|
||||
<%@include file="../components/navbar.jsp" %>
|
||||
<div class="content">
|
||||
<h1>Plongez dans l'excitation de cardRush!</h1>
|
||||
<h1>Plongez dans l'excitation de CardRush!</h1>
|
||||
<p>Défiez votre réactivité et dominez le jeu avec des amis dans cette course effrénée aux cartes ! Rejoignez maintenant pour vivre l'adrénaline.</p>
|
||||
<div class="buttons">
|
||||
<a class="button" href="${pageContext.request.contextPath}/register">S'inscrire</a>
|
||||
@@ -0,0 +1,24 @@
|
||||
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
|
||||
<%@taglib prefix="layout" tagdir="/WEB-INF/tags/layouts" %>
|
||||
<%@taglib prefix="component" tagdir="/WEB-INF/tags/components" %>
|
||||
<%@taglib prefix="form" tagdir="/WEB-INF/tags/forms" %>
|
||||
|
||||
<layout:base>
|
||||
<jsp:attribute name="title">Cards Rush - Connexion</jsp:attribute>
|
||||
<jsp:body>
|
||||
<div class="hero is-light is-fullheight-with-navbar">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-5-tablet is-5-desktop is-5-widescreen">
|
||||
<div class="box">
|
||||
<h1 class="title has-text-centered">Se connecter</h1>
|
||||
<form:login/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</jsp:body>
|
||||
</layout:base>
|
||||
@@ -0,0 +1,61 @@
|
||||
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
|
||||
<%@taglib prefix="layout" tagdir="/WEB-INF/tags/layouts" %>
|
||||
<%@taglib prefix="component" tagdir="/WEB-INF/tags/components" %>
|
||||
<%@taglib prefix="form" tagdir="/WEB-INF/tags/forms" %>
|
||||
|
||||
<layout:base>
|
||||
<jsp:attribute name="title">Menu principal</jsp:attribute>
|
||||
<jsp:body>
|
||||
<div class="hero is-light is-fullheight-with-navbar">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-5-tablet is-5-desktop is-5-widescreen">
|
||||
<component:card>
|
||||
<jsp:attribute name="card_head">
|
||||
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="card_content">
|
||||
<%-- <form:newGame/>--%>
|
||||
</jsp:attribute>
|
||||
</component:card>
|
||||
</div>
|
||||
<div class="column is-5-tablet is-5-desktop is-5-widescreen">
|
||||
<component:connectedUserList/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</jsp:body>
|
||||
</layout:base>
|
||||
|
||||
<%--<!DOCTYPE html>--%>
|
||||
<%--<html>--%>
|
||||
<%--<head>--%>
|
||||
<%-- <title>Cards Rush</title>--%>
|
||||
<%-- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap">--%>
|
||||
<%-- <link href="${pageContext.request.contextPath}/static/css/global.css" rel="stylesheet">--%>
|
||||
<%-- <link href="${pageContext.request.contextPath}/static/css/main-menu.css" rel="stylesheet">--%>
|
||||
<%-- <link href="${pageContext.request.contextPath}/static/css/new-game.css" rel="stylesheet">--%>
|
||||
<%-- <link href="${pageContext.request.contextPath}/static/css/modal.css" rel="stylesheet">--%>
|
||||
<%-- <script src="${pageContext.request.contextPath}/static/js/modal.js" defer></script>--%>
|
||||
<%-- <script src="${pageContext.request.contextPath}/static/js/new-game.js" defer></script>--%>
|
||||
<%-- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">--%>
|
||||
<%-- <script defer src="${pageContext.request.contextPath}/static/js/main-menu.js"></script>--%>
|
||||
<%--</head>--%>
|
||||
<%--<body>--%>
|
||||
<%--<%@include file="../components/navbar.jsp" %>--%>
|
||||
<%--<main>--%>
|
||||
<%-- <section id="main">--%>
|
||||
<%-- <h1 id="title">Cards Rush!</h1>--%>
|
||||
<%-- <div class="main-button">--%>
|
||||
<%-- <button class="modal-toggle button" data-target="#newGameModal">Nouvelle Partie</button>--%>
|
||||
<%-- <button class="modal-toggle button" data-target="#statisticsModal">Statistiques</button>--%>
|
||||
<%-- </div>--%>
|
||||
<%-- </section>--%>
|
||||
<%-- <%@include file="../components/new-game.jsp" %>--%>
|
||||
<%-- <%@include file="../components/statistics.jsp" %>--%>
|
||||
<%--</main>--%>
|
||||
<%--</body>--%>
|
||||
<%--</html>--%>
|
||||
@@ -0,0 +1,76 @@
|
||||
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
|
||||
<%@taglib prefix="layout" tagdir="/WEB-INF/tags/layouts" %>
|
||||
<%@taglib prefix="component" tagdir="/WEB-INF/tags/components" %>
|
||||
<%@taglib prefix="form" tagdir="/WEB-INF/tags/forms" %>
|
||||
|
||||
<layout:base>
|
||||
<jsp:attribute name="title">Cards Rush - Inscription</jsp:attribute>
|
||||
<jsp:body>
|
||||
<div class="hero is-light is-fullheight-with-navbar">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-5-tablet is-5-desktop is-5-widescreen">
|
||||
<div class="box">
|
||||
<h1 class="title has-text-centered">S'inscrire</h1>
|
||||
<form:register/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</jsp:body>
|
||||
</layout:base>
|
||||
|
||||
<%--<!DOCTYPE html>--%>
|
||||
<%--<html>--%>
|
||||
<%--<head>--%>
|
||||
<%-- <title>Register</title>--%>
|
||||
<%-- <link href="${pageContext.request.contextPath}/static/css/global.css" rel="stylesheet">--%>
|
||||
<%-- <link href="${pageContext.request.contextPath}/static/css/login.css" rel="stylesheet">--%>
|
||||
<%-- <script src="${pageContext.request.contextPath}/static/js/register.js" defer></script>--%>
|
||||
<%--</head>--%>
|
||||
<%--<body>--%>
|
||||
<%--<%@include file="../components/navbar.jsp"%>--%>
|
||||
<%--<main>--%>
|
||||
<%-- <div class="flex-column register-gap">--%>
|
||||
<%-- <div>--%>
|
||||
<%-- <h1>S'inscrire</h1>--%>
|
||||
<%-- <form id="register-form" action="${pageContext.request.contextPath}/api/auth/register" method="POST">--%>
|
||||
|
||||
<%-- <label for="email">Email :</label>--%>
|
||||
<%-- <input type="email" id="email" name="email" required>--%>
|
||||
|
||||
<%-- <label for="username">Nom d'utilisateur :</label>--%>
|
||||
<%-- <input type="text" id="username" name="username" required>--%>
|
||||
|
||||
<%-- <label for="password">Mot de passe :</label>--%>
|
||||
<%-- <input type="password" id="password" name="password" required>--%>
|
||||
|
||||
<%-- <label for="confirmPassword">Confirmez le mot de passe :</label>--%>
|
||||
<%-- <input type="password" id="confirmPassword" name="confirmPassword" required>--%>
|
||||
|
||||
<%-- <label for="birthdate">Date de naissance :</label>--%>
|
||||
<%-- <input type="date" id="birthdate" name="birthdate" required>--%>
|
||||
|
||||
<%-- <label for="gender">Genre :</label>--%>
|
||||
<%-- <select name="gender" id="gender" required>--%>
|
||||
<%-- <option value="">--Choisissez une option--</option>--%>
|
||||
<%-- <option value="MALE">Homme</option>--%>
|
||||
<%-- <option value="FEMALE">Femme</option>--%>
|
||||
<%-- <option value="OTHER">Autre</option>--%>
|
||||
<%-- </select>--%>
|
||||
|
||||
<%-- <input class="button" id="register-submit" type="submit" value="Register">--%>
|
||||
<%-- </form>--%>
|
||||
<%-- </div>--%>
|
||||
<%-- <div>--%>
|
||||
<%-- <hr>--%>
|
||||
<%-- <p>Déjà un compte ? <a href="${pageContext.request.contextPath}/login">Se connecter</a></p>--%>
|
||||
<%-- </div>--%>
|
||||
<%-- </div>--%>
|
||||
<%--</main>--%>
|
||||
|
||||
<%--</body>--%>
|
||||
<%--</html>--%>
|
||||
@@ -0,0 +1,12 @@
|
||||
<%@tag description="component/card" pageEncoding="UTF-8" %>
|
||||
<%@attribute name="card_head" fragment="true" %>
|
||||
<%@attribute name="card_content" fragment="true" %>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-head">
|
||||
<jsp:invoke fragment="card_head"/>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<jsp:invoke fragment="card_content"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,85 @@
|
||||
<%@ tag import="com.google.gson.Gson" %>
|
||||
<%@ tag import="uppa.project.database.pojo.User" %>
|
||||
<%@tag description="component/connectedUserList" pageEncoding="UTF-8" %>
|
||||
<%@taglib prefix="component" tagdir="/WEB-INF/tags/components" %>
|
||||
|
||||
<component:card>
|
||||
<jsp:attribute name="card_head">
|
||||
<div class="card-header-title">Utilisateurs connectés</div>
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="card_content">
|
||||
<table id="connectedUserList" class="table is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Utilisateur</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</jsp:attribute>
|
||||
</component:card>
|
||||
|
||||
<script defer type="module">
|
||||
const tbodyElement = document.querySelector('#connectedUserList tbody');
|
||||
|
||||
// effacer ce qu'il y a apres /project_war_exploded
|
||||
const url = new URL(window.location.href);
|
||||
url.pathname = "${pageContext.request.contextPath}/ws/connected-users";
|
||||
url.protocol = "ws:"
|
||||
|
||||
const websocket = new WebSocket(url);
|
||||
|
||||
<%
|
||||
Gson gson = new Gson();
|
||||
User user = (User) request.getSession().getAttribute("user");
|
||||
%>
|
||||
websocket.onopen = () => {
|
||||
const linkUserSession = {
|
||||
type: 'linkUserSession',
|
||||
data: JSON.stringify(<%= gson.toJson(user) %>)
|
||||
}
|
||||
websocket.send(JSON.stringify(linkUserSession));
|
||||
}
|
||||
|
||||
websocket.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
if (data.type === 'userList') {
|
||||
const users = JSON.parse(data.data);
|
||||
updateUserList(users);
|
||||
}
|
||||
}
|
||||
|
||||
websocket.onclose = () => {}
|
||||
websocket.onerror = (error) => {}
|
||||
|
||||
function updateUserList(users) {
|
||||
tbodyElement.innerHTML = '';
|
||||
users.forEach(user => {
|
||||
const trElement = document.createElement('tr');
|
||||
const tdElement = [
|
||||
document.createElement('td'),
|
||||
document.createElement('td')
|
||||
];
|
||||
const buttonElement = document.createElement('button');
|
||||
|
||||
tdElement[0].textContent = user.username;
|
||||
|
||||
// If it's not the current user, we can display the button
|
||||
if (user.id !== <%= user.getId() %>) {
|
||||
buttonElement.classList.add('button', 'is-light');
|
||||
buttonElement.textContent = 'Inviter';
|
||||
|
||||
// TODO Ajouter l'événement click
|
||||
}
|
||||
|
||||
tdElement[1].appendChild(buttonElement);
|
||||
trElement.appendChild(tdElement[0]);
|
||||
trElement.appendChild(tdElement[1]);
|
||||
|
||||
tbodyElement.appendChild(trElement);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,9 @@
|
||||
<%@tag description="component/footer" pageEncoding="UTF-8" %>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="content has-text-centered">
|
||||
<p>
|
||||
<strong>Cards Rush</strong> par Kevin Mitressé & Lucàs Vabre. UPPA M1-TI 2024
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -0,0 +1,35 @@
|
||||
<%@tag description="component/navbar" pageEncoding="UTF-8" %>
|
||||
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="${pageContext.request.contextPath}/">
|
||||
<img src="${pageContext.request.contextPath}/static/img/CardsRushLogoBlack.svg" height="260">
|
||||
</a>
|
||||
|
||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navbarMenu">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="navbarMenu" class="navbar-menu">
|
||||
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item">
|
||||
<div class="buttons">
|
||||
|
||||
<%if (session.getAttribute("user") != null) {%>
|
||||
<%-- TODO: Profil de l'utilisateur--%>
|
||||
<a href="${pageContext.request.contextPath}/profile" class="button is-primary"><strong>Profil</strong></a>
|
||||
<a href="${pageContext.request.contextPath}/logout" class="button is-danger is-light">Déconnexion</a>
|
||||
<% } else {%>
|
||||
<a href="${pageContext.request.contextPath}/register" class="button is-primary"><strong>Inscription</strong></a>
|
||||
<a href="${pageContext.request.contextPath}/login" class="button is-light">Connexion</a>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,123 @@
|
||||
<%@tag description="form/login" pageEncoding="UTF-8" %>
|
||||
|
||||
<form id="login-form" action="${pageContext.request.contextPath}/login" method="post">
|
||||
<div class="field"> <!-- Field Username -->
|
||||
<label class="label" for="username">Nom d'utilisateur</label>
|
||||
<input id="username" placeholder="John Doe" class="input is-fullwidth" required/>
|
||||
</div>
|
||||
<div class="field"> <!-- Field Password -->
|
||||
<label class="label" for="password">Mot de passe</label>
|
||||
<input id="password" class="input is-fullwidth" type="password" required/>
|
||||
</div>
|
||||
<p class="content has-text-right"><a href="${pageContext.request.contextPath}/forgotten-password" class="link">Mot de passe oublié ?</a>
|
||||
</p>
|
||||
<input type="submit" class="button is-primary is-fullwidth" value="Connexion">
|
||||
<hr/>
|
||||
<p class="content has-text-centered"><a href="${pageContext.request.contextPath}/register">S'inscrire</a></p>
|
||||
|
||||
</form>
|
||||
|
||||
<style>
|
||||
.notification {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin: 1em !important;
|
||||
|
||||
transform: translateY(100%);
|
||||
opacity: 0;
|
||||
animation: toast 5s ease forwards;
|
||||
}
|
||||
|
||||
@keyframes toast {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
5% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
95% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0%, 100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
10%, 30%, 50%, 70%, 90% {
|
||||
transform: translateX(-5px);
|
||||
}
|
||||
20%, 40%, 60%, 80% {
|
||||
transform: translateX(5px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script defer type="module">
|
||||
const loginForm = document.querySelector("form#login-form");
|
||||
|
||||
// Form fields
|
||||
const usernameInput = document.querySelector("input#username");
|
||||
const passwordInput = document.querySelector("input#password");
|
||||
|
||||
// Add event listener to the form submission
|
||||
loginForm.addEventListener("submit", onSubmit)
|
||||
|
||||
/**
|
||||
* Handle the form submission with Ajax request
|
||||
* @param event {Event} - Event of the form submission
|
||||
*/
|
||||
function onSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const {action, method} = loginForm;
|
||||
|
||||
const url = new URL(action);
|
||||
url.searchParams.append("username", usernameInput.value);
|
||||
url.searchParams.append("password", passwordInput.value);
|
||||
|
||||
fetch(url, {headers: {"Content-Type": "application/json"}, method})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.code !== 200) throw new Error(data.message);
|
||||
})
|
||||
.then(() => window.location.href = "${pageContext.request.contextPath}/main-menu")
|
||||
.catch(onError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the error of the form submission
|
||||
* @param error {Error} - Error of the form submission
|
||||
*/
|
||||
function onError(error) {
|
||||
console.error("Error:", error)
|
||||
|
||||
// Input fields in red
|
||||
usernameInput.classList.add("is-danger");
|
||||
passwordInput.classList.add("is-danger");
|
||||
|
||||
// Shake the inputs
|
||||
usernameInput.style.animation = "shake 0.5s ease-in-out";
|
||||
passwordInput.style.animation = "shake 0.5s ease-in-out";
|
||||
|
||||
// Notification
|
||||
const notification = document.createElement("div");
|
||||
notification.classList.add("notification", "is-danger");
|
||||
notification.innerHTML = error.message;
|
||||
document.body.appendChild(notification);
|
||||
setTimeout(() => notification.remove(), 5010);
|
||||
}
|
||||
|
||||
// Remove the shake animation at the end of animation
|
||||
usernameInput.addEventListener("animationend", () => usernameInput.style.animation = "");
|
||||
passwordInput.addEventListener("animationend", () => passwordInput.style.animation = "");
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<%@tag description="form/newGame" pageEncoding="UTF-8" %>
|
||||
|
||||
<form id="newGame-form" action="${pageContext.request.contextPath}/main-menu" method="post">
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<style>
|
||||
.notification {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin: 1em !important;
|
||||
|
||||
transform: translateY(100%);
|
||||
opacity: 0;
|
||||
animation: toast 5s ease forwards;
|
||||
}
|
||||
|
||||
@keyframes toast {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
5% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
95% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0%, 100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
10%, 30%, 50%, 70%, 90% {
|
||||
transform: translateX(-5px);
|
||||
}
|
||||
20%, 40%, 60%, 80% {
|
||||
transform: translateX(5px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script defer type="module">
|
||||
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
<%@tag description="form/register" pageEncoding="UTF-8" %>
|
||||
|
||||
<form id="register-form" action="${pageContext.request.contextPath}/register" method="post">
|
||||
<div class="field">
|
||||
<label class="label" for="username">Nom d'utilisateur</label>
|
||||
<input id="username" name="username" placeholder="John Doe" type="text" class="input is-fullwidth" required>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="email">Email</label>
|
||||
<input id="email" name="email" type="email" placeholder="john.doe@mail.com" class="input is-fullwidth" required>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="password">Mot de passe</label>
|
||||
<input id="password" name="password" type="password" class="input is-fullwidth" required>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="repassword">Confirmez le mot de passe</label>
|
||||
<input id="repassword" name="repassword" type="password" class="input is-fullwidth" required>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="birth">Date de naissance</label>
|
||||
<input class="input is-fullwidth" type="date" id="birth" name="birth" required>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="gender">Genre</label>
|
||||
<div class="select is-fullwidth">
|
||||
<select name="gender" id="gender" required>
|
||||
<option selected value="">--Choisissez une option--</option>
|
||||
<option value="MALE">Homme</option>
|
||||
<option value="FEMALE">Femme</option>
|
||||
<option value="OTHER">Autre</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="submit" class="button is-primary is-fullwidth" value="S'inscrire">
|
||||
<hr/>
|
||||
<p class="content has-text-centered">Déjà inscrit ? <a href="${pageContext.request.contextPath}/login">Se connecter</a></p>
|
||||
</form>
|
||||
|
||||
<style>
|
||||
.notification {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin: 1em !important;
|
||||
max-width: 40em;
|
||||
|
||||
transform: translateY(100%);
|
||||
opacity: 0;
|
||||
animation: toast 5s ease forwards;
|
||||
}
|
||||
|
||||
@keyframes toast {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
5% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
95% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script defer type="module">
|
||||
const registerForm = document.querySelector("form#register-form");
|
||||
|
||||
// Form fields
|
||||
const usernameInput = document.querySelector("input#username");
|
||||
const emailInput = document.querySelector("input#email");
|
||||
const passwordInput = document.querySelector("input#password");
|
||||
const repasswordInput = document.querySelector("input#repassword");
|
||||
const birthInput = document.querySelector("input#birth");
|
||||
const genderInput = document.querySelector("select#gender");
|
||||
const submitButton = document.querySelector("input[type=submit]");
|
||||
|
||||
// Add event listener to the form submission
|
||||
registerForm.addEventListener("submit", onSubmit)
|
||||
|
||||
/**
|
||||
* Handle the form submission with Ajax request
|
||||
* @param event {Event} - Event of the form submission
|
||||
*/
|
||||
function onSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
// Check if the password and the confirmation password are the same
|
||||
if (passwordInput.value !== repasswordInput.value) {
|
||||
onError(new Error("Les mots de passe ne correspondent pas"));
|
||||
return;
|
||||
}
|
||||
|
||||
const {action, method} = registerForm;
|
||||
|
||||
const url = new URL(action);
|
||||
url.searchParams.append("username", usernameInput.value);
|
||||
url.searchParams.append("email", emailInput.value);
|
||||
url.searchParams.append("password", passwordInput.value);
|
||||
url.searchParams.append("birth", birthInput.value);
|
||||
url.searchParams.append("gender", genderInput.value);
|
||||
|
||||
submitButton.classList.add("is-loading");
|
||||
fetch(url, {headers: {"Content-Type": "application/json"}, method})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.code !== 200) throw new Error(data.message);
|
||||
})
|
||||
.then(() => window.location.href = "${pageContext.request.contextPath}/login")
|
||||
.catch(onError)
|
||||
.finally(() => submitButton.classList.remove("is-loading"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the error of the form submission
|
||||
* @param error {Error} - Error of the form submission
|
||||
*/
|
||||
function onError(error) {
|
||||
console.error("Error:", error)
|
||||
|
||||
// Input fields in red
|
||||
usernameInput.classList.add("is-danger");
|
||||
emailInput.classList.add("is-danger");
|
||||
passwordInput.classList.add("is-danger");
|
||||
repasswordInput.classList.add("is-danger");
|
||||
birthInput.classList.add("is-danger");
|
||||
genderInput.classList.add("is-danger");
|
||||
|
||||
// Notification
|
||||
const notification = document.createElement("div");
|
||||
notification.classList.add("notification", "is-danger");
|
||||
notification.innerHTML = error.message;
|
||||
document.body.appendChild(notification);
|
||||
setTimeout(() => notification.remove(), 5010);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<%@tag description="Base page layout" pageEncoding="UTF-8" %>
|
||||
<%@attribute name="title" fragment="true" %>
|
||||
<%@attribute name="head" fragment="true" %>
|
||||
|
||||
<%@taglib prefix="component" tagdir="/WEB-INF/tags/components" %>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><jsp:invoke fragment="title"/></title>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.0/css/bulma.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
|
||||
|
||||
<jsp:invoke fragment="head"/>
|
||||
</head>
|
||||
<body>
|
||||
<component:navbar/>
|
||||
|
||||
<jsp:doBody/>
|
||||
|
||||
<component:footer/>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,39 +0,0 @@
|
||||
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title> Cards Rush - Connexion</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap">
|
||||
<link href="${pageContext.request.contextPath}/static/css/global.css" rel="stylesheet">
|
||||
<link href="${pageContext.request.contextPath}/static/css/login.css" rel="stylesheet">
|
||||
<script src="${pageContext.request.contextPath}/static/js/login.js" defer></script>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<%@include file="../components/navbar.jsp"%>
|
||||
<main>
|
||||
<div class="flex-column login-gap">
|
||||
<div>
|
||||
<h1>Se connecter</h1>
|
||||
<form id="login-form" action="${pageContext.request.contextPath}/api/auth/login" method="POST">
|
||||
|
||||
<label id="username-label" for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
|
||||
<label id="password-label" for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
|
||||
<input class="button" id="login-submit" type="submit" value="Login">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<p><a href="${pageContext.request.contextPath}/forgotten-password">Forgotten password?</a></p>
|
||||
<hr>
|
||||
<p>Don't have an account? <a href="${pageContext.request.contextPath}/register">Register</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,32 +0,0 @@
|
||||
<%@ page import="java.util.List" %>
|
||||
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
|
||||
<% List<User> connectedUsers = (List<User>) request.getAttribute("connectedUsers"); %>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Cards Rush</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap">
|
||||
<link href="${pageContext.request.contextPath}/static/css/global.css" rel="stylesheet">
|
||||
<link href="${pageContext.request.contextPath}/static/css/main-menu.css" rel="stylesheet">
|
||||
<link href="${pageContext.request.contextPath}/static/css/new-game.css" rel="stylesheet">
|
||||
<link href="${pageContext.request.contextPath}/static/css/modal.css" rel="stylesheet">
|
||||
<script src="${pageContext.request.contextPath}/static/js/modal.js" defer></script>
|
||||
<script src="${pageContext.request.contextPath}/static/js/new-game.js" defer></script>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script defer src="${pageContext.request.contextPath}/static/js/main-menu.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<%@include file="../components/navbar.jsp"%>
|
||||
<main>
|
||||
<section id="main">
|
||||
<h1 id="title">Cards Rush!</h1>
|
||||
<div class="main-button">
|
||||
<button class="modal-toggle button" data-target="#newGameModal" >Nouvelle Partie</button>
|
||||
<button class="modal-toggle button" data-target="#statisticsModal" >Statistiques</button>
|
||||
</div>
|
||||
</section>
|
||||
<%@include file="../components/new-game.jsp"%>
|
||||
<%@include file="../components/statistics.jsp"%>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,52 +0,0 @@
|
||||
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Register</title>
|
||||
<link href="${pageContext.request.contextPath}/static/css/global.css" rel="stylesheet">
|
||||
<link href="${pageContext.request.contextPath}/static/css/login.css" rel="stylesheet">
|
||||
<script src="${pageContext.request.contextPath}/static/js/register.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<%@include file="../components/navbar.jsp"%>
|
||||
<main>
|
||||
<div class="flex-column register-gap">
|
||||
<div>
|
||||
<h1>S'inscrire</h1>
|
||||
<form id="register-form" action="${pageContext.request.contextPath}/api/auth/register" method="POST">
|
||||
|
||||
<label for="email">Email :</label>
|
||||
<input type="email" id="email" name="email" required>
|
||||
|
||||
<label for="username">Nom d'utilisateur :</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
|
||||
<label for="password">Mot de passe :</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
|
||||
<label for="confirmPassword">Confirmez le mot de passe :</label>
|
||||
<input type="password" id="confirmPassword" name="confirmPassword" required>
|
||||
|
||||
<label for="birthdate">Date de naissance :</label>
|
||||
<input type="date" id="birthdate" name="birthdate" required>
|
||||
|
||||
<label for="gender">Genre :</label>
|
||||
<select name="gender" id="gender" required>
|
||||
<option value="">--Choisissez une option--</option>
|
||||
<option value="MALE">Homme</option>
|
||||
<option value="FEMALE">Femme</option>
|
||||
<option value="OTHER">Autre</option>
|
||||
</select>
|
||||
|
||||
<input class="button" id="register-submit" type="submit" value="Register">
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<hr>
|
||||
<p>Déjà un compte ? <a href="${pageContext.request.contextPath}/login">Se connecter</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -8,4 +8,27 @@
|
||||
uppa.project.listener.SessionServletContextListener
|
||||
</listener-class>
|
||||
</listener>
|
||||
|
||||
<filter>
|
||||
<filter-name>AuthenticationFilter</filter-name>
|
||||
<filter-class>uppa.project.web.filter.AuthenticationFilter</filter-class>
|
||||
</filter>
|
||||
<filter-mapping>
|
||||
<filter-name>AuthenticationFilter</filter-name>
|
||||
<url-pattern>/main-menu</url-pattern>
|
||||
<url-pattern>/profile</url-pattern>
|
||||
<url-pattern>/game</url-pattern>
|
||||
<url-pattern>/logout</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<filter>
|
||||
<filter-name>AlreadyLoggedFilter</filter-name>
|
||||
<filter-class>uppa.project.web.filter.AlreadyLoggedFilter</filter-class>
|
||||
</filter>
|
||||
<filter-mapping>
|
||||
<filter-name>AlreadyLoggedFilter</filter-name>
|
||||
<url-pattern>/login</url-pattern>
|
||||
<url-pattern>/register</url-pattern>
|
||||
<url-pattern>/forgotten-password</url-pattern>
|
||||
</filter-mapping>
|
||||
</web-app>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<%--
|
||||
Created by IntelliJ IDEA.
|
||||
User: lucas
|
||||
Date: 16/04/2024
|
||||
Time: 14:15
|
||||
To change this template use File | Settings | File Templates.
|
||||
--%>
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 13 KiB |
@@ -1,28 +0,0 @@
|
||||
const loginForm = document.getElementById("login-form");
|
||||
|
||||
loginForm.addEventListener("submit", (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const formData = new FormData(loginForm);
|
||||
const data = {};
|
||||
formData.forEach((value, key) => data[key] = value);
|
||||
|
||||
fetch(loginForm.getAttribute("action"), {
|
||||
headers: {"Content-Type": "application/json"}, body: JSON.stringify(data), method: loginForm.getAttribute("method"),
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(user => sessionStorage.setItem("user", JSON.stringify(user)))
|
||||
.then(() => window.location.href = "./main-menu")
|
||||
.catch(error => console.error("Error:", error));
|
||||
});
|
||||
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has('success')) {
|
||||
if (urlParams.get('success') === "account-created") {
|
||||
window.alert("Compte créé avec succès.");
|
||||
}
|
||||
if (urlParams.get('success') === "password-reseted") {
|
||||
window.alert("Mot de passe réinitialisé avec succès.");
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
const session = JSON.parse(sessionStorage.getItem('session'));
|
||||
|
||||
url = new URL(window.location.href);
|
||||
url.protocol = 'ws:';
|
||||
|
||||
const websocket = new WebSocket(url);
|
||||
|
||||
websocket.onopen = () => {
|
||||
const linkUserSession = {
|
||||
type: 'linkUserSession',
|
||||
data: sessionStorage.getItem('user')
|
||||
}
|
||||
websocket.send(JSON.stringify(linkUserSession));
|
||||
}
|
||||
|
||||
websocket.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
if (data.type === 'userList') {
|
||||
console.log(JSON.parse(data.data));
|
||||
}
|
||||
}
|
||||
|
||||
websocket.onclose = () => {}
|
||||
websocket.onerror = (error) => {}
|
||||
@@ -1,21 +0,0 @@
|
||||
const registerForm = document.getElementById("register-form");
|
||||
const confirmPassword = document.getElementById("confirmPassword");
|
||||
|
||||
registerForm.addEventListener("submit", (event) => {
|
||||
event.preventDefault();
|
||||
const formData = new FormData(registerForm);
|
||||
|
||||
const data = {};
|
||||
formData.forEach((value, key) => data[key] = value);
|
||||
|
||||
fetch(registerForm.getAttribute("action"), {
|
||||
method: registerForm.getAttribute("method"),
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(_ => {
|
||||
window.location.href = "./login"
|
||||
})
|
||||
.catch(error => console.error("Error: " + error))
|
||||
});
|
||||
Reference in New Issue
Block a user