mirror of
https://github.com/kmitresse/Cards-Rush.git
synced 2026-05-14 01:21:49 +00:00
feat(DevWeb): Add icons
This commit is contained in:
@@ -22,10 +22,20 @@
|
||||
User user = (User) session.getAttribute("user");
|
||||
%>
|
||||
<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 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>
|
||||
|
||||
<% } else {%>
|
||||
@@ -33,7 +43,12 @@
|
||||
<a href="${pageContext.request.contextPath}/register" class="is-fullwidth button is-primary has-text-white">Inscription</a>
|
||||
</div>
|
||||
<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>
|
||||
|
||||
@@ -3,55 +3,17 @@
|
||||
<form id="forgotten-password-form" action="${pageContext.request.contextPath}/forgotten-password" method="post">
|
||||
<div class="field"> <!-- Field Username -->
|
||||
<label class="label" for="email">Email</label>
|
||||
<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>
|
||||
<input type="submit" class="button is-primary is-fullwidth" value="Envoyer">
|
||||
<div class="help">Veuillez entrer votre email pour obtenir un lien de récupération</div>
|
||||
</div>
|
||||
<input type="submit" class="button is-primary is-fullwidth has-text-white" value="Envoyer">
|
||||
</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 forgottenPasswordForm = document.querySelector("form#forgotten-password-form");
|
||||
|
||||
|
||||
@@ -1,88 +1,47 @@
|
||||
<%@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 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>
|
||||
|
||||
<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");
|
||||
const form = document.querySelector("form#login-form");
|
||||
const inputs = form.querySelectorAll("input[type='text'], input[type='password']");
|
||||
|
||||
// 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) {
|
||||
form.addEventListener("submit", event => {
|
||||
event.preventDefault();
|
||||
|
||||
const {action, method} = loginForm;
|
||||
const {action, method} = form;
|
||||
|
||||
const url = new URL(action);
|
||||
url.searchParams.append("username", usernameInput.value);
|
||||
url.searchParams.append("password", passwordInput.value);
|
||||
inputs.forEach(input => url.searchParams.append(input.getAttribute("name"), input.value));
|
||||
|
||||
fetch(url, {headers: {"Content-Type": "application/json"}, method})
|
||||
.then(res => res.json())
|
||||
@@ -90,34 +49,42 @@
|
||||
if (data.code !== 200) throw new Error(data.message);
|
||||
})
|
||||
.then(() => window.location.href = "${pageContext.request.contextPath}/main-menu")
|
||||
.catch(onError);
|
||||
}
|
||||
.catch((error) => {
|
||||
console.log(error)
|
||||
|
||||
/**
|
||||
* 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";
|
||||
// Input animation
|
||||
inputs.forEach(input => {
|
||||
input.classList.add("is-danger");
|
||||
input.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 = "");
|
||||
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);
|
||||
|
||||
// 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>
|
||||
|
||||
|
||||
@@ -3,22 +3,34 @@
|
||||
<form id="register-form" action="${pageContext.request.contextPath}/register" method="post">
|
||||
<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>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="email">Email</label>
|
||||
<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 class="field">
|
||||
<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 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 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 class="field">
|
||||
@@ -28,65 +40,27 @@
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="gender">Genre</label>
|
||||
<div class="control has-icons-left">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="gender" id="gender" required>
|
||||
<option selected value="">--Choisissez une option--</option>
|
||||
<option selected value="">- Choisissez une option -</option>
|
||||
<option value="MALE">Homme</option>
|
||||
<option value="FEMALE">Femme</option>
|
||||
<option value="OTHER">Autre</option>
|
||||
</select>
|
||||
</div>
|
||||
<span class="icon is-left"><i class="fa-solid fa-venus-mars"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
|
||||
<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]");
|
||||
const inputs = registerForm.querySelectorAll("input, select");
|
||||
|
||||
// Add event listener to the form submission
|
||||
registerForm.addEventListener("submit", onSubmit)
|
||||
@@ -98,8 +72,11 @@
|
||||
function onSubmit(event) {
|
||||
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
|
||||
if (passwordInput.value !== repasswordInput.value) {
|
||||
if (password.value !== repassword.value) {
|
||||
onError(new Error("Les mots de passe ne correspondent pas"));
|
||||
return;
|
||||
}
|
||||
@@ -107,13 +84,8 @@
|
||||
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);
|
||||
inputs.forEach(input => url.searchParams.append(input.name, input.value));
|
||||
|
||||
submitButton.classList.add("is-loading");
|
||||
fetch(url, {headers: {"Content-Type": "application/json"}, method})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
@@ -121,7 +93,6 @@
|
||||
})
|
||||
.then(() => window.location.href = "${pageContext.request.contextPath}/login")
|
||||
.catch(onError)
|
||||
.finally(() => submitButton.classList.remove("is-loading"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,18 +103,29 @@
|
||||
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");
|
||||
inputs.forEach(input => input.classList.add("is-danger"));
|
||||
|
||||
// Notification
|
||||
const notification = document.createElement("div");
|
||||
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);
|
||||
|
||||
setTimeout(() => notification.remove(), 5010);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,52 +4,23 @@
|
||||
<input type="hidden" id="token" name="token" value="${pageContext.request.getParameter("token")}">
|
||||
<div class="field">
|
||||
<label class="label" for="password">Mot de passe</label>
|
||||
<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 class="field">
|
||||
<label class="label" for="repassword">Confirmez le mot de passe</label>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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 resetPasswordForm = document.querySelector("form#reset-password-form");
|
||||
const submitButton = document.querySelector("input[type=submit]");
|
||||
|
||||
Reference in New Issue
Block a user