mirror of
https://github.com/kmitresse/Cards-Rush.git
synced 2026-07-09 13:27:45 +00:00
feat(DevWeb): Add icons
This commit is contained in:
@@ -22,10 +22,20 @@
|
|||||||
User user = (User) session.getAttribute("user");
|
User user = (User) session.getAttribute("user");
|
||||||
%>
|
%>
|
||||||
<div class="navbar-item">
|
<div class="navbar-item">
|
||||||
<a href="${pageContext.request.contextPath}/profile" class="is-fullwidth button is-light"><%= user.getUsername() %></a>
|
<a href="${pageContext.request.contextPath}/profile" class="is-fullwidth button is-light">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-user"></i>
|
||||||
|
</span>
|
||||||
|
<span><%= user.getUsername() %></span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-item">
|
<div class="navbar-item">
|
||||||
<a href="${pageContext.request.contextPath}/logout" class="is-fullwidth button is-light is-danger">Déconnexion</a>
|
<a href="${pageContext.request.contextPath}/logout" class="is-fullwidth button is-light is-danger">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-door-open"></i>
|
||||||
|
</span>
|
||||||
|
<span>Déconnexion</span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% } else {%>
|
<% } else {%>
|
||||||
@@ -33,7 +43,12 @@
|
|||||||
<a href="${pageContext.request.contextPath}/register" class="is-fullwidth button is-primary has-text-white">Inscription</a>
|
<a href="${pageContext.request.contextPath}/register" class="is-fullwidth button is-primary has-text-white">Inscription</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-item">
|
<div class="navbar-item">
|
||||||
<a href="${pageContext.request.contextPath}/login" class="is-fullwidth button is-light">Connexion</a>
|
<a href="${pageContext.request.contextPath}/login" class="is-fullwidth button is-light">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-right-to-bracket"></i>
|
||||||
|
</span>
|
||||||
|
<span>Connexion</span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,55 +3,17 @@
|
|||||||
<form id="forgotten-password-form" action="${pageContext.request.contextPath}/forgotten-password" method="post">
|
<form id="forgotten-password-form" action="${pageContext.request.contextPath}/forgotten-password" method="post">
|
||||||
<div class="field"> <!-- Field Username -->
|
<div class="field"> <!-- Field Username -->
|
||||||
<label class="label" for="email">Email</label>
|
<label class="label" for="email">Email</label>
|
||||||
<input id="email" placeholder="johndoe@exemple.com" class="input is-fullwidth" required/>
|
<div class="control has-icons-left">
|
||||||
|
<input id="email" placeholder="johndoe@exemple.com" class="input is-fullwidth" required/>
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-envelope"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="help">Veuillez entrer votre email pour obtenir un lien de récupération</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="submit" class="button is-primary is-fullwidth" value="Envoyer">
|
<input type="submit" class="button is-primary is-fullwidth has-text-white" value="Envoyer">
|
||||||
</form>
|
</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 defer type="module">
|
||||||
const forgottenPasswordForm = document.querySelector("form#forgotten-password-form");
|
const forgottenPasswordForm = document.querySelector("form#forgotten-password-form");
|
||||||
|
|
||||||
|
|||||||
@@ -1,88 +1,47 @@
|
|||||||
<%@tag description="form/login" pageEncoding="UTF-8" %>
|
<%@tag description="form/login" pageEncoding="UTF-8" %>
|
||||||
|
|
||||||
<form id="login-form" action="${pageContext.request.contextPath}/login" method="post">
|
<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 has-text-white is-fullwidth" value="Connexion">
|
|
||||||
<hr/>
|
|
||||||
<p class="content has-text-centered"><a href="${pageContext.request.contextPath}/register">S'inscrire</a></p>
|
|
||||||
|
|
||||||
|
<!-- Field Username -->
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="username">Nom d'utilisateur</label>
|
||||||
|
<div class="control has-icons-left">
|
||||||
|
<input id="username" name="username" placeholder="John Doe" type="text" class="input is-fullwidth" required/>
|
||||||
|
<span class="icon is-left">
|
||||||
|
<i class="fas fa-user"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Field Password -->
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="password">Mot de passe</label>
|
||||||
|
<div class="control has-icons-left">
|
||||||
|
<input id="password" name="password" placeholder="Mot de passe" class="input is-fullwidth" type="password" required/>
|
||||||
|
<span class="icon is-left">
|
||||||
|
<i class="fas fa-lock"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</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 has-text-white is-fullwidth" value="Connexion">
|
||||||
</form>
|
</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 defer type="module">
|
||||||
const loginForm = document.querySelector("form#login-form");
|
const form = document.querySelector("form#login-form");
|
||||||
|
const inputs = form.querySelectorAll("input[type='text'], input[type='password']");
|
||||||
|
|
||||||
// Form fields
|
form.addEventListener("submit", event => {
|
||||||
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();
|
event.preventDefault();
|
||||||
|
|
||||||
const {action, method} = loginForm;
|
const {action, method} = form;
|
||||||
|
|
||||||
const url = new URL(action);
|
const url = new URL(action);
|
||||||
url.searchParams.append("username", usernameInput.value);
|
inputs.forEach(input => url.searchParams.append(input.getAttribute("name"), input.value));
|
||||||
url.searchParams.append("password", passwordInput.value);
|
|
||||||
|
|
||||||
fetch(url, {headers: {"Content-Type": "application/json"}, method})
|
fetch(url, {headers: {"Content-Type": "application/json"}, method})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
@@ -90,34 +49,42 @@
|
|||||||
if (data.code !== 200) throw new Error(data.message);
|
if (data.code !== 200) throw new Error(data.message);
|
||||||
})
|
})
|
||||||
.then(() => window.location.href = "${pageContext.request.contextPath}/main-menu")
|
.then(() => window.location.href = "${pageContext.request.contextPath}/main-menu")
|
||||||
.catch(onError);
|
.catch((error) => {
|
||||||
}
|
console.log(error)
|
||||||
|
|
||||||
/**
|
// Input animation
|
||||||
* Handle the error of the form submission
|
inputs.forEach(input => {
|
||||||
* @param error {Error} - Error of the form submission
|
input.classList.add("is-danger");
|
||||||
*/
|
input.style.animation = "shake 0.5s ease-in-out"
|
||||||
function onError(error) {
|
});
|
||||||
console.error("Error:", error)
|
|
||||||
|
|
||||||
// Input fields in red
|
// Notification
|
||||||
usernameInput.classList.add("is-danger");
|
const notification = document.createElement("div");
|
||||||
passwordInput.classList.add("is-danger");
|
notification.classList.add("notification", "is-danger");
|
||||||
|
|
||||||
// Shake the inputs
|
const notificationTitle = document.createElement("p");
|
||||||
usernameInput.style.animation = "shake 0.5s ease-in-out";
|
notificationTitle.classList.add("title", "is-6");
|
||||||
passwordInput.style.animation = "shake 0.5s ease-in-out";
|
notificationTitle.innerHTML = "Erreur";
|
||||||
|
|
||||||
// Notification
|
const notificationIcon = document.createElement("span");
|
||||||
const notification = document.createElement("div");
|
notificationIcon.classList.add("icon");
|
||||||
notification.classList.add("notification", "is-danger");
|
notificationIcon.innerHTML = "<i class='fas fa-exclamation-triangle'></i>";
|
||||||
notification.innerHTML = error.message;
|
|
||||||
document.body.appendChild(notification);
|
|
||||||
setTimeout(() => notification.remove(), 5010);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the shake animation at the end of animation
|
const notificationMessage = document.createElement("p");
|
||||||
usernameInput.addEventListener("animationend", () => usernameInput.style.animation = "");
|
notificationMessage.classList.add("subtitle", "is-6");
|
||||||
passwordInput.addEventListener("animationend", () => passwordInput.style.animation = "");
|
notificationMessage.innerHTML = error.message;
|
||||||
|
|
||||||
|
notificationTitle.appendChild(notificationIcon);
|
||||||
|
notification.appendChild(notificationTitle);
|
||||||
|
notification.appendChild(notificationMessage);
|
||||||
|
document.body.appendChild(notification);
|
||||||
|
|
||||||
|
// Remove notification and animation after 5s
|
||||||
|
setTimeout(() => notification.remove(), 5010);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// On animation end, remove class and animation
|
||||||
|
inputs.forEach(input => input.addEventListener("animationend", () => input.style.animation = ""));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,22 +3,34 @@
|
|||||||
<form id="register-form" action="${pageContext.request.contextPath}/register" method="post">
|
<form id="register-form" action="${pageContext.request.contextPath}/register" method="post">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="username">Nom d'utilisateur</label>
|
<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 class="control has-icons-left">
|
||||||
|
<input id="username" name="username" placeholder="John Doe" type="text" class="input is-fullwidth" required>
|
||||||
|
<span class="icon is-left"><i class="fas fa-user"></i></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="email">Email</label>
|
<label class="label" for="email">Email</label>
|
||||||
<input id="email" name="email" type="email" placeholder="johndoe@exemple.com" class="input is-fullwidth" required>
|
<div class="control has-icons-left">
|
||||||
|
<input id="email" name="email" type="email" placeholder="johndoe@exemple.com" class="input is-fullwidth" required>
|
||||||
|
<span class="icon is-left"><i class="fas fa-envelope"></i></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="password">Mot de passe</label>
|
<label class="label" for="password">Mot de passe</label>
|
||||||
<input id="password" name="password" type="password" class="input is-fullwidth" required>
|
<div class="control has-icons-left">
|
||||||
|
<input id="password" name="password" placeholder="Mot de passe" type="password" class="input is-fullwidth" required>
|
||||||
|
<span class="icon is-left"><i class="fas fa-lock"></i></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="repassword">Confirmez le mot de passe</label>
|
<label class="label" for="repassword">Confirmez le mot de passe</label>
|
||||||
<input id="repassword" name="repassword" type="password" class="input is-fullwidth" required>
|
<div class="control has-icons-left">
|
||||||
|
<input id="repassword" name="repassword" placeholder="Répétez le mot de passe" type="password" class="input is-fullwidth" required>
|
||||||
|
<span class="icon is-left"><i class="fas fa-lock"></i></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
@@ -28,65 +40,27 @@
|
|||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="gender">Genre</label>
|
<label class="label" for="gender">Genre</label>
|
||||||
<div class="select is-fullwidth">
|
<div class="control has-icons-left">
|
||||||
<select name="gender" id="gender" required>
|
<div class="select is-fullwidth">
|
||||||
<option selected value="">--Choisissez une option--</option>
|
<select name="gender" id="gender" required>
|
||||||
<option value="MALE">Homme</option>
|
<option selected value="">- Choisissez une option -</option>
|
||||||
<option value="FEMALE">Femme</option>
|
<option value="MALE">Homme</option>
|
||||||
<option value="OTHER">Autre</option>
|
<option value="FEMALE">Femme</option>
|
||||||
</select>
|
<option value="OTHER">Autre</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<span class="icon is-left"><i class="fa-solid fa-venus-mars"></i></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="submit" class="button has-text-white is-primary is-fullwidth" value="S'inscrire">
|
<input type="submit" class="button has-text-white 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>
|
</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">
|
<script defer type="module">
|
||||||
const registerForm = document.querySelector("form#register-form");
|
const registerForm = document.querySelector("form#register-form");
|
||||||
|
|
||||||
// Form fields
|
// Form fields
|
||||||
const usernameInput = document.querySelector("input#username");
|
const inputs = registerForm.querySelectorAll("input, select");
|
||||||
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
|
// Add event listener to the form submission
|
||||||
registerForm.addEventListener("submit", onSubmit)
|
registerForm.addEventListener("submit", onSubmit)
|
||||||
@@ -98,8 +72,11 @@
|
|||||||
function onSubmit(event) {
|
function onSubmit(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
const password = registerForm.querySelector("input[name='password']");
|
||||||
|
const repassword = registerForm.querySelector("input[name='repassword']");
|
||||||
|
|
||||||
// Check if the password and the confirmation password are the same
|
// Check if the password and the confirmation password are the same
|
||||||
if (passwordInput.value !== repasswordInput.value) {
|
if (password.value !== repassword.value) {
|
||||||
onError(new Error("Les mots de passe ne correspondent pas"));
|
onError(new Error("Les mots de passe ne correspondent pas"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -107,13 +84,8 @@
|
|||||||
const {action, method} = registerForm;
|
const {action, method} = registerForm;
|
||||||
|
|
||||||
const url = new URL(action);
|
const url = new URL(action);
|
||||||
url.searchParams.append("username", usernameInput.value);
|
inputs.forEach(input => url.searchParams.append(input.name, input.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})
|
fetch(url, {headers: {"Content-Type": "application/json"}, method})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@@ -121,7 +93,6 @@
|
|||||||
})
|
})
|
||||||
.then(() => window.location.href = "${pageContext.request.contextPath}/login")
|
.then(() => window.location.href = "${pageContext.request.contextPath}/login")
|
||||||
.catch(onError)
|
.catch(onError)
|
||||||
.finally(() => submitButton.classList.remove("is-loading"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,18 +103,29 @@
|
|||||||
console.error("Error:", error)
|
console.error("Error:", error)
|
||||||
|
|
||||||
// Input fields in red
|
// Input fields in red
|
||||||
usernameInput.classList.add("is-danger");
|
inputs.forEach(input => input.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
|
// Notification
|
||||||
const notification = document.createElement("div");
|
const notification = document.createElement("div");
|
||||||
notification.classList.add("notification", "is-danger");
|
notification.classList.add("notification", "is-danger");
|
||||||
notification.innerHTML = error.message;
|
|
||||||
|
const notificationTitle = document.createElement("p");
|
||||||
|
notificationTitle.classList.add("title", "is-6");
|
||||||
|
notificationTitle.innerHTML = "Erreur";
|
||||||
|
|
||||||
|
const notificationIcon = document.createElement("span");
|
||||||
|
notificationIcon.classList.add("icon");
|
||||||
|
notificationIcon.innerHTML = "<i class='fas fa-exclamation-triangle'></i>";
|
||||||
|
|
||||||
|
const notificationMessage = document.createElement("p");
|
||||||
|
notificationMessage.classList.add("subtitle", "is-6");
|
||||||
|
notificationMessage.innerHTML = error.message;
|
||||||
|
|
||||||
|
notificationTitle.appendChild(notificationIcon);
|
||||||
|
notification.appendChild(notificationTitle);
|
||||||
|
notification.appendChild(notificationMessage);
|
||||||
document.body.appendChild(notification);
|
document.body.appendChild(notification);
|
||||||
|
|
||||||
setTimeout(() => notification.remove(), 5010);
|
setTimeout(() => notification.remove(), 5010);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -4,111 +4,82 @@
|
|||||||
<input type="hidden" id="token" name="token" value="${pageContext.request.getParameter("token")}">
|
<input type="hidden" id="token" name="token" value="${pageContext.request.getParameter("token")}">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="password">Mot de passe</label>
|
<label class="label" for="password">Mot de passe</label>
|
||||||
<input id="password" name="password" type="password" class="input is-fullwidth" required>
|
<div class="control has-icons-left">
|
||||||
|
<input id="password" name="password" type="password" class="input is-fullwidth" required>
|
||||||
|
<span class="icon is-small is-left"><i class="fas fa-lock"></i></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="repassword">Confirmez le mot de passe</label>
|
<label class="label" for="repassword">Confirmez le mot de passe</label>
|
||||||
<input id="repassword" name="repassword" type="password" class="input is-fullwidth" required>
|
<div class="control has-icons-left">
|
||||||
|
<input id="repassword" name="repassword" type="password" class="input is-fullwidth" required>
|
||||||
|
<span class="icon is-small is-left"><i class="fas fa-lock"></i></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="submit" class="button is-primary is-fullwidth" value="Envoyer">
|
<input type="submit" class="button is-primary is-fullwidth" value="Envoyer">
|
||||||
<hr/>
|
|
||||||
<p class="content has-text-centered">Déjà inscrit ? <a href="${pageContext.request.contextPath}/login">Se connecter</a></p>
|
|
||||||
</form>
|
</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">
|
<script defer type="module">
|
||||||
const resetPasswordForm = document.querySelector("form#reset-password-form");
|
const resetPasswordForm = document.querySelector("form#reset-password-form");
|
||||||
const submitButton = document.querySelector("input[type=submit]");
|
const submitButton = document.querySelector("input[type=submit]");
|
||||||
|
|
||||||
// Form fields
|
// Form fields
|
||||||
const tokenInput = document.querySelector("input#token");
|
const tokenInput = document.querySelector("input#token");
|
||||||
const passwordInput = document.querySelector("input#password");
|
const passwordInput = document.querySelector("input#password");
|
||||||
const repasswordInput = document.querySelector("input#repassword");
|
const repasswordInput = document.querySelector("input#repassword");
|
||||||
|
|
||||||
// Add event listener to the form submission
|
// Add event listener to the form submission
|
||||||
resetPasswordForm.addEventListener("submit", onSubmit)
|
resetPasswordForm.addEventListener("submit", onSubmit)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the form submission with Ajax request
|
* Handle the form submission with Ajax request
|
||||||
* @param event {Event} - Event of the form submission
|
* @param event {Event} - Event of the form submission
|
||||||
*/
|
*/
|
||||||
function onSubmit(event) {
|
function onSubmit(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
// Check if the password and the confirmation password are the same
|
// Check if the password and the confirmation password are the same
|
||||||
if (passwordInput.value !== repasswordInput.value) {
|
if (passwordInput.value !== repasswordInput.value) {
|
||||||
onError(new Error("Les mots de passe ne correspondent pas"));
|
onError(new Error("Les mots de passe ne correspondent pas"));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {action, method} = resetPasswordForm;
|
||||||
|
|
||||||
|
const url = new URL(action);
|
||||||
|
url.searchParams.append("token", tokenInput.value);
|
||||||
|
url.searchParams.append("password", passwordInput.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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const {action, method} = resetPasswordForm;
|
/**
|
||||||
|
* Handle the error of the form submission
|
||||||
|
* @param error {Error} - Error of the form submission
|
||||||
|
*/
|
||||||
|
function onError(error) {
|
||||||
|
console.error("Error:", error)
|
||||||
|
|
||||||
const url = new URL(action);
|
// Input fields in red
|
||||||
url.searchParams.append("token", tokenInput.value);
|
passwordInput.classList.add("is-danger");
|
||||||
url.searchParams.append("password", passwordInput.value);
|
repasswordInput.classList.add("is-danger");
|
||||||
|
|
||||||
submitButton.classList.add("is-loading");
|
// Notification
|
||||||
fetch(url, {headers: {"Content-Type": "application/json"}, method})
|
const notification = document.createElement("div");
|
||||||
.then(res => res.json())
|
notification.classList.add("notification", "is-danger");
|
||||||
.then(data => {
|
notification.innerHTML = error.message;
|
||||||
if (data.code !== 200) throw new Error(data.message);
|
document.body.appendChild(notification);
|
||||||
})
|
setTimeout(() => notification.remove(), 5010);
|
||||||
.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
|
|
||||||
passwordInput.classList.add("is-danger");
|
|
||||||
repasswordInput.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>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user